1 package com.ca.commons.naming; 2 3 import javax.naming.*; 4 import javax.naming.directory.*; 5 6 import java.util.*; 7 import java.util.logging.Logger ; 8 import java.util.logging.Level ; 9 import java.text.CollationKey ; 10 import java.text.Collator ; 11 12 import com.ca.commons.cbutil.*; 13 import com.ca.commons.jndi.SchemaOps; 14 15 24 25 29 30 public class DXAttribute extends BasicAttribute implements Comparable 31 { 32 protected boolean isString = true; protected boolean isASN1 = false; 35 36 static boolean appendBinaryOption = false; 38 String name; String syntaxOID; String syntaxDesc; String description; 43 private static final String STRING = "string"; 44 private static final String BYTE_ARRAY = "bytes"; 45 private static final String ASN1 = "asn1"; 46 static Hashtable knownAttributeTypes; 48 static SchemaOps schema; 50 51 private CollationKey collationKey; private static Collator myCollator = Collator.getInstance(); 54 private final static Logger log = Logger.getLogger(DXAttribute.class.getName()); 56 static 57 { 58 knownAttributeTypes = new Hashtable(100); 59 } 60 61 65 66 public DXAttribute(String ID) 67 { 68 super(ID); 69 init(); 70 } 71 72 77 78 public DXAttribute(String ID, Object value) 79 { 80 super(ID, value); 81 init(); 82 } 83 84 88 89 public DXAttribute(Attribute att) 90 { 91 super(att.getID()); 92 try 93 { 94 addValues(att.getAll()); 95 } 96 catch (NamingException e) 97 { 98 log.log(Level.WARNING, "error reading attribute values for attribute " + getID() + "\n", e); 99 } 100 101 setName(att.getID()); 103 init(); 104 } 105 106 111 112 public DXAttribute(String ID, NamingEnumeration values) 113 { 114 super(ID); 115 addValues(values); 116 init(); 117 } 118 119 123 public void addValues(NamingEnumeration values) 124 { 125 try 126 { 127 while (values.hasMore()) 128 { 129 add(values.next()); 130 } 131 } 132 catch (NamingException e) 133 { 134 log.log(Level.WARNING, "error adding values for attribute " + getID(), e); 135 } 136 } 137 138 143 public void sort() 144 { 145 if (values.size()<2) 146 return; 148 try 149 { 150 Collections.sort((List)values); 152 } 153 catch (ClassCastException e) 154 { 155 } 157 catch (UnsupportedOperationException e) 158 { 159 } 161 } 162 163 168 public static void setDefaultSchema(SchemaOps defaultSchema) 169 { 170 schema = defaultSchema; 171 } 172 173 176 protected void init() 177 { 178 setAttributeType(); 180 181 collationKey = myCollator.getCollationKey(getID()); 183 } 184 185 188 189 protected void setAttributeType() 190 { 191 String ID = getID(); 193 194 if ("SYNTAXNAMENUMERICOIDDESCEQUALITY".indexOf(ID) != -1) return; 196 197 ID = ID.toLowerCase(); 198 199 if (knownAttributeTypes.get(ID) != null) 201 { 202 isString = STRING.equals(knownAttributeTypes.get(ID)); 203 isASN1 = ASN1.equals(knownAttributeTypes.get(ID)); 204 } 205 else if (ID.endsWith(";binary")) 207 { 208 isString = false; 209 isASN1 = true; 210 } 211 else if (schema != null) 212 { 213 setAttributeTypeFromSchema(); } 215 else { 217 try 218 { 219 if (size() > 0) 220 { 221 Object value = get(); 222 223 isString = (value == null || value instanceof String ); 224 225 if (!isString) 226 isASN1 = isKnownASN1Attribute(ID); } 228 } 229 catch (NamingException e) 230 { 231 log.log(Level.WARNING, "Unexpected error reading value from attribute " + ID, e); 232 } 233 } 234 235 updateTypesHashtable(ID); 236 } 237 238 private void updateTypesHashtable(String ID) 239 { 240 if (knownAttributeTypes.contains(ID) == false) 241 { 242 if (isString) 243 knownAttributeTypes.put(ID, STRING); 244 else if (isASN1) 245 knownAttributeTypes.put(ID, ASN1); 246 else 247 knownAttributeTypes.put(ID, BYTE_ARRAY); 248 } 249 } 250 251 254 255 public static boolean isEmpty(Attribute att) 256 { 257 if (att == null || att.size() == 0) 258 { 259 return true; 260 } 261 else if (att.size() == 1) 262 { 263 Object val = null; 264 try 265 { 266 val = att.get(); 267 } 268 catch (NamingException e) 269 { 270 return true; } 272 273 if (val == null || "".equals(val)) 274 return true; 275 } 276 277 return false; 278 } 279 286 public static boolean isStringSyntax(String syntaxName) 287 { 288 if (syntaxName == null) 289 return true; 291 int pos = syntaxName.indexOf("1.3.6.1.4.1.1466.115.121.1."); 292 if (pos == -1) 293 return true; 295 String number = syntaxName.substring(pos + "1.3.6.1.4.1.1466.115.121.1.".length()); 297 298 if (number.length() > 2) 299 { 300 number = number.substring(0, 2); 301 char c = number.charAt(1); 302 if (Character.isDigit(c) == false) 303 number = number.substring(0, 1); 304 } 305 306 try 307 { 308 int finalNumber = Integer.parseInt(number); 309 310 switch (finalNumber) 311 { 312 case 4: 313 return false; case 5: 315 return false; case 8: 317 return false; case 9: 319 return false; case 10: 321 return false; case 28: 323 return false; case 40: 325 return false; default: 327 return true; 328 } 329 } 330 catch (NumberFormatException e) 331 { 332 log.log(Level.WARNING, "Unexpected error parsing syntax: " + syntaxName, e); 333 return true; 334 } 335 336 } 337 338 345 public static boolean isASN1Syntax(String syntaxName) 346 { 347 if (syntaxName == null) 348 return false; 349 350 int pos = syntaxName.indexOf("1.3.6.1.4.1.1466.115.121.1."); 351 if (pos == -1) 352 return false; 353 354 String number = syntaxName.substring(pos + "1.3.6.1.4.1.1466.115.121.1.".length()); 355 356 if (number.length() > 2) 357 { 358 number = number.substring(0, 2); 359 char c = number.charAt(1); 360 if (Character.isDigit(c) == false) 361 number = number.substring(0, 1); 362 } 363 364 try 365 { 366 int finalNumber = Integer.parseInt(number); 367 368 switch (finalNumber) 369 { 370 case 5: 371 return true; case 8: 373 return true; case 9: 375 return true; case 10: 377 return true; default: 379 return false; 380 } 381 } 382 catch (NumberFormatException e) 383 { 384 log.log(Level.WARNING, "Unexpected error parsing syntax: " + syntaxName, e); 385 return false; 386 } 387 388 } 389 390 398 public void setAttributeTypeFromSchema() 399 { 400 if (schema != null) 401 { 402 try 403 { 404 String attributeNameInSchema = "AttributeDefinition/" + getID(); 405 Attributes atts = schema.getAttributes(attributeNameInSchema); 406 407 Attribute syntaxAttribute = null; 408 while (atts!=null && (syntaxAttribute = atts.get("SUP")) != null) 409 { 410 atts = schema.getAttributes("AttributeDefinition/" + syntaxAttribute.get().toString()); 411 } 412 if (atts!=null) 413 syntaxAttribute = atts.get("SYNTAX"); 414 415 if (syntaxAttribute != null) 416 { 417 syntaxOID = syntaxAttribute.toString(); 418 isString = isStringSyntax(syntaxOID); 419 if (!isString) 420 isASN1 = isASN1Syntax(syntaxOID); 421 } 422 else 423 { 424 log.info(" Can't find SYNTAX for... " + getID()); 425 } 426 } 427 catch (NamingException e) { 431 try 432 { 433 Attributes atts = schema.getAttributes("AttributeDefinition/" + getID() + ";binary"); 434 435 if (atts != null) 437 { 438 isString = false; 439 isASN1 = true; 440 } 441 } 442 catch (Exception e2) { 444 log.log(Level.INFO, "can't find syntax for attribute " + getID(), e); 445 } 446 } 447 } 448 else 449 { 450 log.fine("no schema available"); 451 } 452 } 453 454 460 public boolean isBinary() 461 { 462 return !isString(); 463 } 464 465 466 470 public boolean isString() 471 { 472 return isString; 473 } 474 475 481 public void setBinary(boolean bin) 482 { 483 setString(!bin); 484 } 485 486 490 public void setString(boolean stringStatus) 491 { 492 knownAttributeTypes.put(getID(), (stringStatus)?STRING:BYTE_ARRAY); 493 isString = stringStatus; 494 } 495 496 505 506 public String schemaLookup(String schemaEntry, String schemaAttribute) 507 { 508 if (schema == null) 509 return null; 510 else 511 return schema.schemaLookup(schemaEntry, schemaAttribute); 512 } 513 514 518 public boolean hasOptions() 519 { 520 if (description == null) getDescription(); 522 523 if (description == null || description == "" || description.indexOf("LIST:") < 0) 524 return false; 525 526 return true; 527 } 528 529 534 535 public String [] getOptions() 536 { 537 if (description == null) 538 getDescription(); 539 if (description == null || description == "") 540 return new String [0]; 541 542 int len = description.length(); 544 int pos = description.indexOf("LIST:"); 545 if (pos < 0) return new String [0]; 546 pos += 5; 547 int next = pos; 548 549 Vector resVect = new Vector(); 550 resVect.add(""); 551 while (pos < len && pos > 0) 553 { 554 next = description.indexOf(',', next + 1); 555 if (next < 0) 556 { 557 resVect.add(description.substring(pos)); 558 pos = 0; 559 } 560 else if (description.charAt(next - 1) != '\\') 561 { 562 resVect.add(description.substring(pos, next)); 563 pos = next + 1; 564 } 565 else 566 { 567 next++; } 569 } 570 571 String [] result = new String [resVect.size()]; 573 for (int i = 0; i < resVect.size(); i++) 574 result[i] = unEscape((String ) resVect.elementAt(i)); 575 576 return result; 577 } 578 579 public String unEscape(String escapeMe) 580 { 581 int slashpos = escapeMe.indexOf('\\'); 582 while (slashpos >= 0) 583 { 584 escapeMe = escapeMe.substring(0, slashpos) + escapeMe.substring(slashpos + 1); 585 slashpos = escapeMe.indexOf('\\'); 586 } 587 return escapeMe; 588 } 589 590 595 596 public String getSyntaxOID() 597 { 598 if (syntaxOID == null) 599 setAttributeTypeFromSchema(); 601 if (syntaxOID == null) 602 return "<unknown>"; 603 else 604 return syntaxOID; 605 } 606 607 608 611 public String getSyntaxDesc() 612 { 613 if (syntaxDesc == null) 614 syntaxDesc = schemaLookup("SyntaxDefinition/" + getSyntaxOID(), "DESC"); 615 return syntaxDesc; 616 } 617 618 619 public String getSyntaxName() 620 { 621 if (syntaxOID == null) 622 setAttributeTypeFromSchema(); 624 if (syntaxOID == null) 625 return "<unknown>"; 626 else 627 return schema.translateOID(syntaxOID); 628 } 629 630 631 635 public void setName(String newName) 636 { 637 name = newName; 638 } 639 640 public String getName() 641 { 642 if (name == null) 643 name = schemaLookup("AttributeDefinition/" + getID(), "NAME"); 644 if (name == null) 645 name = getID(); 646 647 return name; 648 } 649 650 655 656 public String getDescription() 657 { 658 if (description == null) 659 { 660 description = schemaLookup("AttributeDefinition/" + getID(), "DESC"); 661 if (description == null) description = ""; } 664 return description; 665 } 666 667 672 public String toString() 673 { 674 return getID(); 675 } 676 677 680 681 public String toDebugString() 682 { 683 int count = 1; 684 try 685 { 686 StringBuffer result = new StringBuffer ().append("att: ").append(getID()).append(" (size=").append(size()).append(") "); 687 688 NamingEnumeration vals = getAll(); 689 if (!isString) 690 { 691 result.append(" (Byte Array) "); 692 while (vals.hasMore()) 693 { 694 try 695 { 696 byte[] b = (byte[]) vals.next(); 697 result.append("\n ").append((count++)).append(":").append(((b == null) ? "null" : CBBase64.binaryToString(b))); 698 } 699 catch (ClassCastException cce) 700 { 701 result.append("\n ").append((count++)).append(": <error - not a byte array>"); 702 } 703 } 704 } 705 else 706 { 707 while (vals.hasMore()) 708 { 709 Object o = vals.next(); 710 result.append("\n ").append((count++)).append(":").append(((o == null) ? "null" : o.toString())); 711 } 712 } 713 714 return result.append("\n").toString(); 715 } 716 catch (NamingException e) 717 { 718 log.log(Level.WARNING, "error listing values for " + getID(), e); 719 return (getID() + " (error listing values)"); 720 } 721 722 723 } 724 725 public static void setVerboseBinary(boolean status) 728 { 729 appendBinaryOption = status; 730 log.fine("setting isNonString attribute status to " + status); 731 } 732 733 737 738 741 public String getID() 742 { 743 String id = super.getID(); 744 if (appendBinaryOption && !(id.endsWith(";binary"))) 745 { 746 if (isASN1) 749 { 750 id = id + ";binary"; 751 log.info("appending ;binary to attribute name "+id); 752 } 753 754 } 755 return id; 756 } 757 758 764 765 public boolean isKnownASN1Attribute(String id) 766 { 767 String search = id.toLowerCase(); 768 if (search.indexOf("certificate") >= 0) 769 return true; 770 else if (search.indexOf("revocation") >= 0) 771 return true; 772 else if (search.indexOf("supportedalgorithms") >= 0) 773 return true; 774 else if (search.indexOf("userpkcs12") >= 0) 775 return true; 776 777 return false; 778 } 779 780 781 788 789 public Object [] getValues() 790 { 791 Object [] values = new String [size()]; 792 793 try 794 { 795 for (int i = 0; i < size(); i++) 796 values[i] = get(i); 797 return values; 798 } 799 catch (NamingException e) 800 { 801 return new String []{}; 802 } 803 } 804 805 806 809 public void trim() 810 { 811 for (int i = size() - 1; i > 0; i--) 812 { 813 Object o = null; 814 try 815 { 816 o = get(i); 817 if (o == null || "".equals(o)) 818 { 819 remove(i); 820 } 821 } 822 catch (NamingException e) { 824 log.log(Level.WARNING, "Bad Attribute value in DXAttribute - removing ", e); 825 remove(i); 827 } 828 } 829 } 830 831 public void setOrdered(boolean state) 832 { 833 ordered = state; 834 } 835 836 837 843 844 public boolean isSingleValued() 845 { 846 return schema.isAttributeSingleValued(getName()); 847 } 848 849 858 public void setCollationKey(CollationKey key) 859 { 860 collationKey = key; 861 } 862 863 869 public CollationKey getCollationKey() 870 { 871 return collationKey; 872 } 873 874 882 public int compareTo(Object o) 883 { 884 return collationKey.compareTo(((DXAttribute) o).getCollationKey()); 885 } 886 } | Popular Tags |