001/* 002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 003 * 004 * Copyright (c) 2005 Sun Microsystems Inc. All Rights Reserved 005 * 006 * The contents of this file are subject to the terms 007 * of the Common Development and Distribution License 008 * (the License). You may not use this file except in 009 * compliance with the License. 010 * 011 * You can obtain a copy of the License at 012 * https://opensso.dev.java.net/public/CDDLv1.0.html or 013 * opensso/legal/CDDLv1.0.txt 014 * See the License for the specific language governing 015 * permission and limitations under the License. 016 * 017 * When distributing Covered Code, include this CDDL 018 * Header Notice in each file and include the License file 019 * at opensso/legal/CDDLv1.0.txt. 020 * If applicable, add the following below the CDDL Header, 021 * with the fields enclosed by brackets [] replaced by 022 * your own identifying information: 023 * "Portions Copyrighted [year] [name of copyright owner]" 024 * 025 * $Id: Attr.java,v 1.4 2009/01/28 05:34:49 ww203982 Exp $ 026 * 027 * Portions Copyrighted 2011-2015 ForgeRock AS. 028 */ 029 030package com.iplanet.services.ldap; 031 032import java.util.ArrayList; 033import java.util.List; 034import java.util.Locale; 035import java.util.StringTokenizer; 036 037import org.forgerock.opendj.ldap.Attribute; 038import org.forgerock.opendj.ldap.Attributes; 039 040/** 041 * Represents an attribute value pair in UMS. The value of an attribute can be 042 * of multiple values. 043 * @supported.api 044 */ 045public class Attr implements java.io.Serializable, java.lang.Cloneable { 046 047 String _name; 048 049 private List<String> _stringValues; 050 051 private List<byte[]> _byteValues; 052 053 private Attribute _ldapAttribute; 054 055 /** 056 * Default constructor 057 * @supported.api 058 */ 059 public Attr() { 060 } 061 062 /** 063 * Constructs an attribute value pair with no value. 064 * 065 * @param name 066 * attribute name 067 * @supported.api 068 */ 069 public Attr(String name) { 070 _name = name.toLowerCase(); 071 } 072 073 /** 074 * Construct an attribute value pair with a single string value. 075 * 076 * @param name 077 * the name of attribute 078 * @param value 079 * string value of attribute 080 * @supported.api 081 */ 082 public Attr(String name, String value) { 083 _name = name.toLowerCase(); 084 _stringValues = new ArrayList<>(1); 085 _stringValues.add(value); 086 } 087 088 /** 089 * Construct an attribute value pair with a multiple string values. 090 * 091 * @param name 092 * the name of attribute 093 * @param value 094 * multiple string values of attribute 095 * @supported.api 096 */ 097 public Attr(String name, String[] value) { 098 _name = name.toLowerCase(); 099 int size = value.length; 100 _stringValues = new ArrayList<>(size); 101 for (int i = 0; i < size; i++) { 102 _stringValues.add(value[i]); 103 } 104 } 105 106 /** 107 * Constructs an attribute value pair with byte array. 108 * 109 * @param name 110 * attribute name 111 * @param value 112 * byte array as input for value 113 * @supported.api 114 */ 115 public Attr(String name, byte[] value) { 116 _name = name.toLowerCase(); 117 _byteValues = new ArrayList<>(1); 118 _byteValues.add(value); 119 } 120 121 /** 122 * Constructs an attribute value pair with array of byte array. 123 * 124 * @param name 125 * attribute name 126 * @param value 127 * array of byte array as input for value 128 * @supported.api 129 */ 130 public Attr(String name, byte[][] value) { 131 _name = name.toLowerCase(); 132 _byteValues = new ArrayList<>(1); 133 int size = value.length; 134 for (int i = 0; i < size; i++) { 135 _byteValues.add(value[i]); 136 } 137 } 138 139 /** 140 * Construct an attribute based on a LDAP attribute 141 * 142 * @param attr 143 * ldap attribute to construct from 144 */ 145 public Attr(Attribute attr) { 146 _name = attr.getAttributeDescriptionAsString().toLowerCase(); 147 _ldapAttribute = attr; // attr.clone() ? 148 } 149 150 /** 151 * Map to a ldap attribute 152 * 153 * @return an ldap attribute 154 */ 155 public Attribute toLDAPAttribute() { 156 Attribute ldapAttribute = null; 157 if (_stringValues != null) { 158 int size = _stringValues.size(); 159 if (size == 0) { 160 ldapAttribute = Attributes.emptyAttribute(_name); 161 } else if (size == 1) { 162 ldapAttribute = Attributes.singletonAttribute(_name, _stringValues.get(0)); 163 } else if (size > 1) { 164 ldapAttribute = Attributes.emptyAttribute(_name); 165 for (String value : _stringValues) { 166 ldapAttribute.add(value); 167 } 168 } 169 } else if (_byteValues != null) { 170 ldapAttribute = Attributes.emptyAttribute(_name); 171 for (byte[] value : _byteValues) { 172 ldapAttribute.add(value); // clone? 173 } 174 } else if (_ldapAttribute != null) { 175 ldapAttribute = _ldapAttribute; // clone? 176 } else if (_name != null) { 177 ldapAttribute = Attributes.emptyAttribute(_name); 178 } 179 return ldapAttribute; 180 } 181 182 /** 183 * Set value of an attribute 184 * 185 * @param value 186 * the attribute value to be set 187 * @supported.api 188 */ 189 public void setValue(String value) { 190 if (_stringValues == null) { 191 setupStringValues(); 192 } 193 _stringValues.clear(); 194 addValue(value); 195 } 196 197 /** 198 * Add a string value to the attribute 199 * 200 * @param value 201 * value to be added to the attribute 202 * @supported.api 203 */ 204 public void addValue(String value) { 205 if (_stringValues == null) { 206 setupStringValues(); 207 } 208 if (!_stringValues.contains(value)) { 209 _stringValues.add(value); 210 } 211 } 212 213 /** 214 * Add mulitple string values to the attribute 215 * 216 * @param values 217 * string values to be added to the attribute 218 * @supported.api 219 */ 220 public void addValues(String[] values) { 221 int size = values.length; 222 for (int i = 0; i < size; i++) { 223 addValue(values[i]); 224 } 225 } 226 227 /** 228 * Remove a specified string value in the attribute 229 * 230 * @param value 231 * specified value to be remvoed from the value array 232 * @supported.api 233 */ 234 public void removeValue(String value) { 235 if (_stringValues == null) { 236 setupStringValues(); 237 } 238 int size = _stringValues.size(); 239 for (int i = 0; i < size; i++) { 240 if (_stringValues.get(i).equals(value)) { 241 _stringValues.remove(i); 242 break; 243 } 244 } 245 } 246 247 /** 248 * Set value of an attribute 249 * 250 * @param value 251 * the attribute value to be set 252 * @supported.api 253 */ 254 public void setValue(byte[] value) { 255 if (_byteValues == null) { 256 setupByteValues(); 257 } 258 _byteValues.clear(); 259 addValue(value); 260 } 261 262 /** 263 * Add a byte array value to the attribute 264 * 265 * @param value 266 * byte array value to be added to the attribute 267 * @supported.api 268 */ 269 public void addValue(byte[] value) { 270 if (_byteValues == null) { 271 setupByteValues(); 272 } 273 _byteValues.add(value); // clone? 274 } 275 276 /** 277 * Add a list byte array values to the attribute 278 * 279 * @param values 280 * of byte array values to be added to the attribute 281 * @supported.api 282 */ 283 public void addValues(byte[][] values) { 284 int size = values.length; 285 for (int i = 0; i < size; i++) { 286 addValue(values[i]); 287 } 288 } 289 290 /** 291 * Remove a specified string value in the attribute 292 * 293 * @param value 294 * specified value to be remvoed from the value array 295 * @supported.api 296 */ 297 public void removeValue(byte[] value) { 298 if (_byteValues == null) { 299 setupByteValues(); 300 } 301 int size = _byteValues.size(); 302 for (int i = 0; i < size; i++) { 303 // we might have to change the logic here to compare each byte 304 if (_byteValues.get(i).equals(value)) { 305 _byteValues.remove(i); 306 break; 307 } 308 } 309 } 310 311 /** 312 * Get name of an UMS attribute 313 * 314 * @return name of an UMS attribute 315 * @supported.api 316 */ 317 public String getName() { 318 return _name; 319 } 320 321 /** 322 * Get name of attribute in a given Locale 323 * 324 * @param locale 325 * Given locale for the attribute name to return 326 * @return name of an UMS attribute 327 * @supported.api 328 */ 329 public String getName(Locale locale) { 330 return Attr.getName(_name, locale); 331 } 332 333 /** 334 * Get attribute name with locale input. 335 * 336 * @param attrName 337 * name of the attribute 338 * @param locale 339 * desired locale for the attribute 340 * @return attribute name with locale attached for retrieval 341 * @supported.api 342 */ 343 static public String getName(String attrName, Locale locale) { 344 String name = null; 345 String baseName = getBaseName(attrName); 346 if (locale == null) { 347 name = baseName; 348 } else { 349 350 // TODO: ??? check if locale.toString method provides the 351 // contents in locale.getLanguage, locale.getSubtype, and 352 // locale.getVariant methods that match the language subtypes 353 // in LDAP. 354 // 355 String localeStr = locale.toString(); 356 if (localeStr.length() > 0) { 357 StringBuilder sb = new StringBuilder(baseName); 358 sb.append(";lang-"); 359 sb.append(localeStr); 360 name = sb.toString(); 361 } 362 } 363 return name; 364 } 365 366 /** 367 * Get base name for the attribute. e.g, the base name 368 * of "cn;lang-en" or "cn;lang-ja" is "cn" 369 * 370 * @return basename of an attribute 371 * @supported.api 372 */ 373 public String getBaseName() { 374 if (_name != null) { 375 return getBaseName(getName()); 376 } 377 return null; 378 } 379 380 /** 381 * Get base name for an attribute name. e.g, the base 382 * name of "cn;lang-en" or "cn;lang-ja" is "cn" 383 * 384 * @return basename of the given attribute name 385 * @supported.api 386 */ 387 static public String getBaseName(String attrName) { 388 String basename = attrName; 389 StringTokenizer st = new StringTokenizer(attrName, ";"); 390 if( st.hasMoreElements() ) 391 // First element is base name 392 basename = (String)st.nextElement(); 393 return basename; 394 } 395 396 /** 397 * Get one string value of the attribute 398 * 399 * @return one value of the attribute 400 * @supported.api 401 */ 402 public String getValue() { 403 String value = null; 404 if (_stringValues == null) { 405 setupStringValues(); 406 } 407 if (!_stringValues.isEmpty()) { 408 value = (String) _stringValues.get(0); 409 } 410 return value; 411 } 412 413 /** 414 * Get the string values of the attribute 415 * 416 * @return the values in an string array 417 * @supported.api 418 */ 419 public String[] getStringValues() { 420 // Returning a colletion would be better, but would break existing 421 // higher level 422 // code 423 424 // com.iplanet.ums.Pauser.pause("10", "_stringValues : " + 425 // _stringValues); 426 // com.iplanet.ums.Pauser.pause("10", "_stringValue : " + _stringValue); 427 // System.out.println("_stringValue : " + _stringValue); 428 // System.out.println("_stringValues : " + _stringValues); 429 String[] stringValues = null; 430 if (_stringValues == null) { 431 setupStringValues(); 432 } 433 int size = _stringValues.size(); 434 stringValues = new String[size]; 435 for (int i = 0; i < size; i++) { 436 stringValues[i] = (String) _stringValues.get(i); 437 } 438 return stringValues; 439 } 440 441 /** 442 * Checks whether the given value already exist for 443 * the attribute 444 * 445 * @param value 446 * the value to check for 447 * @return <code>true</code> if the value already exists, 448 * <code>false</code> otherwise 449 * @supported.api 450 */ 451 public boolean contains(String value) { 452 boolean contained = false; 453 if (_stringValues == null) { 454 setupStringValues(); 455 } 456 int size = _stringValues.size(); 457 for (int i = 0; i < size; i++) { 458 if (_stringValues.get(i).equals(value)) { 459 contained = true; 460 break; 461 } 462 } 463 return contained; 464 } 465 466 /** 467 * Get one byte[] value of the attribute Returning a 468 * colletion would be better, but will not be consistent with the method 469 * getStringValues() 470 * 471 * @return one byte[] value 472 * @supported.api 473 */ 474 public byte[] getByteValue() { 475 // Not cloning the value before returning. Do we need to clone? 476 byte[] value = null; 477 if (_byteValues == null) { 478 setupByteValues(); 479 } 480 if (!_byteValues.isEmpty()) { 481 value = (byte[]) _byteValues.get(0); 482 } 483 return value; 484 } 485 486 /** 487 * Get the byte[] values of the attribute 488 * 489 * @return the byte[] values in array 490 * @supported.api 491 */ 492 public byte[][] getByteValues() { 493 // Not cloning the values before returning. Do we need to clone? 494 byte[][] byteValues = null; 495 if (_byteValues == null) { 496 setupByteValues(); 497 } 498 int size = _byteValues.size(); 499 byteValues = new byte[size][]; 500 for (int i = 0; i < size; i++) { 501 byteValues[i] = (byte[]) _byteValues.get(i); 502 } 503 return byteValues; 504 } 505 506 /** 507 * Checks whether the given value already exist for 508 * the attribute 509 * 510 * @param value 511 * the value to check for 512 * @return <code>true</code> if the value already exists, 513 * <code>false</code> otherwise 514 * @supported.api 515 */ 516 public boolean contains(byte[] value) { 517 boolean contained = false; 518 if (_byteValues == null) { 519 setupByteValues(); 520 } 521 int size = _byteValues.size(); 522 for (int i = 0; i < size; i++) { 523 // we might have to change the logic here to compare each byte 524 if (_byteValues.get(i).equals(value)) { 525 contained = true; 526 break; 527 } 528 } 529 return contained; 530 } 531 532 /** 533 * Get the number of values of the attribute 534 * 535 * @return The number of values of the attribute 536 * @supported.api 537 */ 538 public int size() { 539 int size = 0; 540 if (_stringValues != null) { 541 size = _stringValues.size(); 542 } else if (_byteValues != null) { 543 size = _byteValues.size(); 544 } else if (_ldapAttribute != null) { 545 size = _ldapAttribute.size(); 546 } 547 return size; 548 } 549 550 /** 551 * Return a copy of the object 552 * 553 * @return A copy of the object 554 * @supported.api 555 */ 556 public Object clone() { 557 /* 558 * TO DO : revisit and do proper deep cloning? 559 */ 560 Attr theClone = null; 561 try { 562 theClone = (Attr) super.clone(); 563 } catch (Exception e) { 564 } 565 if (_stringValues != null) { 566 theClone._stringValues = new ArrayList<>(_stringValues); 567 } 568 if (_byteValues != null) { 569 theClone._byteValues = new ArrayList<>(_byteValues); 570 } else if (_ldapAttribute != null) { 571 theClone._ldapAttribute = _ldapAttribute; // clone? 572 } 573 return theClone; 574 } 575 576 /** 577 * Retrieves the string representation of an attribute 578 * 579 * @return string representation of the attribute. 580 * @supported.api 581 */ 582 public String toString() { 583 if (_stringValues == null) { 584 setupStringValues(); 585 } 586 return "Name : " + _name + _stringValues; 587 } 588 589 /** 590 */ 591 private void setupStringValues() { 592 if (_ldapAttribute != null) { 593 String[] values = _ldapAttribute.toArray(new String[0]); 594 int size = values.length; 595 _stringValues = new ArrayList<>(size); 596 for (int i = 0; i < size; i++) { 597 _stringValues.add(values[i]); 598 } 599 } else { 600 _stringValues = new ArrayList<>(); 601 } 602 } 603 604 /** 605 */ 606 private void setupByteValues() { 607 if (_ldapAttribute != null) { 608 byte[][] values = _ldapAttribute.toArray(new byte[0][]); 609 int size = values.length; 610 _byteValues = new ArrayList<>(size); 611 for (int i = 0; i < size; i++) { 612 _byteValues.add(values[i]); 613 } 614 } else { 615 _byteValues = new ArrayList<>(); 616 } 617 } 618 619}