1 7 package com.ca.commons.jndi; 8 9 import javax.naming.directory.*; 10 import javax.naming.NamingException ; 11 import javax.naming.NamingEnumeration ; 12 import java.util.*; 13 14 import java.util.logging.*; 15 16 17 24 public class SchemaOps 25 { 26 protected DirContext ctx = null; Attributes rawSchemaAttributes = null; private String schemaRoot = null; HashMap oids = new HashMap(1000); 31 final static String subschemaAttributeName = "subschemaSubentry"; 32 33 private final static Logger log = Logger.getLogger(SchemaOps.class.getName()); 34 35 public static final String SCHEMA_FAKE_OBJECT_CLASS_NAME = "synthetic_JXplorer_schema_object"; 36 private static final BasicAttribute schemaObjectClassAttribute = new BasicAttribute("objectClass"); 37 38 private ArrayList fullObjectClassArray = null; 40 private ArrayList fullAttributeNameArray = null; 42 static 43 { 44 schemaObjectClassAttribute.add("top"); 45 schemaObjectClassAttribute.add(SCHEMA_FAKE_OBJECT_CLASS_NAME); 46 } 47 48 54 public SchemaOps(DirContext context) 55 throws NamingException 56 { 57 ctx = context; 58 if (ctx == null) 59 { 60 setSchemaRoot("cn=schema"); loadOIDs(); 63 return; 64 } 65 66 log.finest("Reading Schema info from directory context"); 67 68 setSchemaRoot(getSchemaRoot()); 69 rawSchemaAttributes = getRawSchema(); 70 71 74 loadOIDs(); 75 } 76 77 82 84 public SchemaOps(Attributes rawSchemaAtts) 85 { 87 ctx = null; 88 rawSchemaAttributes = rawSchemaAtts; 89 90 setSchemaRoot("cn=schema"); 91 loadOIDs(); 92 log.finest("SCHEMA ROOTX:" + getSchemaRoot()); 93 } 94 95 102 public String translateOID(String oid) 103 { 104 if (oids.containsKey(oid)) 105 return (String ) oids.get(oid); 106 else 107 return oid; 108 } 109 110 113 protected void loadOIDs() 114 { 115 loadOIDsFromSchema(); 116 117 loadStaticOIDs(); 118 } 119 120 123 protected void loadOIDsFromSchema() 124 { 125 if (rawSchemaAttributes == null) 126 return; 127 128 try 129 { 130 NamingEnumeration rawSchemaAtts = rawSchemaAttributes.getAll(); 131 while (rawSchemaAtts.hasMoreElements()) 132 { 133 Attribute rawSchemaAtt = (Attribute) rawSchemaAtts.nextElement(); 134 NamingEnumeration values = rawSchemaAtt.getAll(); 135 136 while (values.hasMoreElements()) 137 { 138 String value = (String ) values.nextElement(); 139 if (value.indexOf('(') == -1) 140 log.finest("skipping non schema attribute: " + rawSchemaAtt.getID() + ":" + value); 141 else 142 oids.put(getOID(value), getFirstName(value)); 143 } 144 } 145 } 146 catch (NamingException e) 147 { 148 log.log(Level.WARNING, "Unable to read schema oids: ", e); 149 } 150 } 151 152 153 protected void loadStaticOIDs() 154 { 155 159 oids.put("1.3.6.1.4.1.1466.115.121.1.1", "ACI Item"); 160 oids.put("1.3.6.1.4.1.1466.115.121.1.2", "Access Point"); 161 oids.put("1.3.6.1.4.1.1466.115.121.1.3", "Attribute Type Description"); 162 oids.put("1.3.6.1.4.1.1466.115.121.1.4", "Audio"); 163 oids.put("1.3.6.1.4.1.1466.115.121.1.5", "Binary"); 164 oids.put("1.3.6.1.4.1.1466.115.121.1.6", "Bit String"); 165 oids.put("1.3.6.1.4.1.1466.115.121.1.7", "Boolean"); 166 oids.put("1.3.6.1.4.1.1466.115.121.1.8", "Certificate"); 167 oids.put("1.3.6.1.4.1.1466.115.121.1.9", "Certificate List"); 168 oids.put("1.3.6.1.4.1.1466.115.121.1.10", "Certificate Pair"); 169 oids.put("1.3.6.1.4.1.1466.115.121.1.11", "Country String"); 170 oids.put("1.3.6.1.4.1.1466.115.121.1.12", "DN"); 171 oids.put("1.3.6.1.4.1.1466.115.121.1.13", "Data Quality Syntax"); 172 oids.put("1.3.6.1.4.1.1466.115.121.1.14", "Delivery Method"); 173 oids.put("1.3.6.1.4.1.1466.115.121.1.15", "Directory String"); 174 oids.put("1.3.6.1.4.1.1466.115.121.1.16", "DIT Content Rule Description"); 175 oids.put("1.3.6.1.4.1.1466.115.121.1.17", "DIT Structure Rule Description"); 176 oids.put("1.3.6.1.4.1.1466.115.121.1.18", "DL Submit Permission"); 177 oids.put("1.3.6.1.4.1.1466.115.121.1.19", "DSA Quality Syntax"); 178 oids.put("1.3.6.1.4.1.1466.115.121.1.20", "DSE Type"); 179 oids.put("1.3.6.1.4.1.1466.115.121.1.21", "Enhanced Guide"); 180 oids.put("1.3.6.1.4.1.1466.115.121.1.22", "Facsimile Telephone Number"); 181 oids.put("1.3.6.1.4.1.1466.115.121.1.23", "Fax"); 182 oids.put("1.3.6.1.4.1.1466.115.121.1.24", "Generalized Time"); 183 oids.put("1.3.6.1.4.1.1466.115.121.1.25", "Guide"); 184 oids.put("1.3.6.1.4.1.1466.115.121.1.26", "IA5 String"); 185 oids.put("1.3.6.1.4.1.1466.115.121.1.27", "INTEGER"); 186 oids.put("1.3.6.1.4.1.1466.115.121.1.28", "JPEG"); 187 oids.put("1.3.6.1.4.1.1466.115.121.1.54", "LDAP Syntax Description"); 188 oids.put("1.3.6.1.4.1.1466.115.121.1.56", "LDAP Schema Definition"); 189 oids.put("1.3.6.1.4.1.1466.115.121.1.57", "LDAP Schema Description"); 190 oids.put("1.3.6.1.4.1.1466.115.121.1.29", "Master And Shadow Access Points"); 191 oids.put("1.3.6.1.4.1.1466.115.121.1.30", "Matching Rule Description"); 192 oids.put("1.3.6.1.4.1.1466.115.121.1.31", "Matching Rule Use Description"); 193 oids.put("1.3.6.1.4.1.1466.115.121.1.32", "Mail Preference"); 194 oids.put("1.3.6.1.4.1.1466.115.121.1.33", "MHS OR Address"); 195 oids.put("1.3.6.1.4.1.1466.115.121.1.55", "Modify Rights"); 196 oids.put("1.3.6.1.4.1.1466.115.121.1.34", "Name And Optional UID"); 197 oids.put("1.3.6.1.4.1.1466.115.121.1.35", "Name Form Description"); 198 oids.put("1.3.6.1.4.1.1466.115.121.1.36", "Numeric String"); 199 oids.put("1.3.6.1.4.1.1466.115.121.1.37", "Object Class Description"); 200 oids.put("1.3.6.1.4.1.1466.115.121.1.40", "Octet String"); 201 oids.put("1.3.6.1.4.1.1466.115.121.1.38", "OID"); 202 oids.put("1.3.6.1.4.1.1466.115.121.1.39", "Other Mailbox"); 203 oids.put("1.3.6.1.4.1.1466.115.121.1.41", "Postal Address"); 204 oids.put("1.3.6.1.4.1.1466.115.121.1.42", "Protocol Information"); 205 oids.put("1.3.6.1.4.1.1466.115.121.1.43", "Presentation Address"); 206 oids.put("1.3.6.1.4.1.1466.115.121.1.44", "Printable String"); 207 oids.put("1.3.6.1.4.1.1466.115.121.1.58", "Substring Assertion"); 208 oids.put("1.3.6.1.4.1.1466.115.121.1.45", "Subtree Specification"); 209 oids.put("1.3.6.1.4.1.1466.115.121.1.46", "Supplier Information"); 210 oids.put("1.3.6.1.4.1.1466.115.121.1.47", "Supplier Or Consumer"); 211 oids.put("1.3.6.1.4.1.1466.115.121.1.48", "Supplier And Consumer"); 212 oids.put("1.3.6.1.4.1.1466.115.121.1.49", "Supported Algorithm"); 213 oids.put("1.3.6.1.4.1.1466.115.121.1.50", "Telephone Number"); 214 oids.put("1.3.6.1.4.1.1466.115.121.1.51", "Teletex Terminal Identifier"); 215 oids.put("1.3.6.1.4.1.1466.115.121.1.52", "Telex Number"); 216 oids.put("1.3.6.1.4.1.1466.115.121.1.53", "UTC Time"); 217 218 oids.put("1.3.6.1.4.1.1466.115.121.1.1", "ACI Item"); 219 oids.put("1.3.6.1.4.1.1466.115.121.1.2", "Access Point"); 220 oids.put("1.3.6.1.4.1.1466.115.121.1.3", "Attribute Type Description"); 221 oids.put("1.3.6.1.4.1.1466.115.121.1.4", "Audio"); 222 oids.put("1.3.6.1.4.1.1466.115.121.1.5", "Binary"); 223 oids.put("1.3.6.1.4.1.1466.115.121.1.6", "Bit String"); 224 oids.put("1.3.6.1.4.1.1466.115.121.1.7", "Boolean"); 225 oids.put("1.3.6.1.4.1.1466.115.121.1.8", "Certificate"); 226 oids.put("1.3.6.1.4.1.1466.115.121.1.9", "Certificate List"); 227 oids.put("1.3.6.1.4.1.1466.115.121.1.10", "Certificate Pair"); 228 oids.put("1.3.6.1.4.1.1466.115.121.1.11", "Country String"); 229 oids.put("1.3.6.1.4.1.1466.115.121.1.12", "DN"); 230 oids.put("1.3.6.1.4.1.1466.115.121.1.13", "Data Quality Syntax"); 231 oids.put("1.3.6.1.4.1.1466.115.121.1.14", "Delivery Method"); 232 oids.put("1.3.6.1.4.1.1466.115.121.1.15", "Directory String"); 233 oids.put("1.3.6.1.4.1.1466.115.121.1.16", "DIT Content Rule Description"); 234 oids.put("1.3.6.1.4.1.1466.115.121.1.17", "DIT Structure Rule Description"); 235 oids.put("1.3.6.1.4.1.1466.115.121.1.18", "DL Submit Permission"); 236 oids.put("1.3.6.1.4.1.1466.115.121.1.19", "DSA Quality Syntax"); 237 oids.put("1.3.6.1.4.1.1466.115.121.1.20", "DSE Type"); 238 oids.put("1.3.6.1.4.1.1466.115.121.1.21", "Enhanced Guide"); 239 oids.put("1.3.6.1.4.1.1466.115.121.1.22", "Facsimile Telephone Number"); 240 oids.put("1.3.6.1.4.1.1466.115.121.1.23", "Fax"); 241 oids.put("1.3.6.1.4.1.1466.115.121.1.24", "Generalized Time"); 242 oids.put("1.3.6.1.4.1.1466.115.121.1.25", "Guide"); 243 oids.put("1.3.6.1.4.1.1466.115.121.1.26", "IA5 String"); 244 oids.put("1.3.6.1.4.1.1466.115.121.1.27", "INTEGER"); 245 oids.put("1.3.6.1.4.1.1466.115.121.1.28", "JPEG"); 246 oids.put("1.3.6.1.4.1.1466.115.121.1.54", "LDAP Syntax Description"); 247 oids.put("1.3.6.1.4.1.1466.115.121.1.56", "LDAP Schema Definition"); 248 oids.put("1.3.6.1.4.1.1466.115.121.1.57", "LDAP Schema Description"); 249 oids.put("1.3.6.1.4.1.1466.115.121.1.29", "Master And Shadow Access Points"); 250 oids.put("1.3.6.1.4.1.1466.115.121.1.30", "Matching Rule Description"); 251 oids.put("1.3.6.1.4.1.1466.115.121.1.31", "Matching Rule Use Description"); 252 oids.put("1.3.6.1.4.1.1466.115.121.1.32", "Mail Preference"); 253 oids.put("1.3.6.1.4.1.1466.115.121.1.33", "MHS OR Address"); 254 oids.put("1.3.6.1.4.1.1466.115.121.1.55", "Modify Rights"); 255 oids.put("1.3.6.1.4.1.1466.115.121.1.34", "Name And Optional UID"); 256 oids.put("1.3.6.1.4.1.1466.115.121.1.35", "Name Form Description"); 257 oids.put("1.3.6.1.4.1.1466.115.121.1.36", "Numeric String"); 258 oids.put("1.3.6.1.4.1.1466.115.121.1.37", "Object Class Description"); 259 oids.put("1.3.6.1.4.1.1466.115.121.1.40", "Octet String"); 260 oids.put("1.3.6.1.4.1.1466.115.121.1.38", "OID"); 261 oids.put("1.3.6.1.4.1.1466.115.121.1.39", "Other Mailbox"); 262 oids.put("1.3.6.1.4.1.1466.115.121.1.41", "Postal Address"); 263 oids.put("1.3.6.1.4.1.1466.115.121.1.42", "Protocol Information"); 264 oids.put("1.3.6.1.4.1.1466.115.121.1.43", "Presentation Address"); 265 oids.put("1.3.6.1.4.1.1466.115.121.1.44", "Printable String"); 266 oids.put("1.3.6.1.4.1.1466.115.121.1.58", "Substring Assertion"); 267 oids.put("1.3.6.1.4.1.1466.115.121.1.45", "Subtree Specification"); 268 oids.put("1.3.6.1.4.1.1466.115.121.1.46", "Supplier Information"); 269 oids.put("1.3.6.1.4.1.1466.115.121.1.47", "Supplier Or Consumer"); 270 oids.put("1.3.6.1.4.1.1466.115.121.1.48", "Supplier And Consumer"); 271 oids.put("1.3.6.1.4.1.1466.115.121.1.49", "Supported Algorithm"); 272 oids.put("1.3.6.1.4.1.1466.115.121.1.50", "Telephone Number"); 273 oids.put("1.3.6.1.4.1.1466.115.121.1.51", "Teletex Terminal Identifier"); 274 oids.put("1.3.6.1.4.1.1466.115.121.1.52", "Telex Number"); 275 oids.put("1.3.6.1.4.1.1466.115.121.1.53", "UTC Time"); 276 } 277 278 284 protected void debugPrint(String syntaxRoot) 285 throws NamingException 286 { 287 System.out.println("---DEBUG PRINT---"); 288 System.out.println("schema root: " + getSchemaRoot()); 289 if (syntaxRoot.length() > 0 && syntaxRoot.startsWith("schema=") == false) 290 syntaxRoot = "schema=" + syntaxRoot; 291 292 tabbedDebugPrint(syntaxRoot, ""); 293 System.out.println("-----------------"); 294 } 295 296 protected void tabbedDebugPrint(String syntaxElement, String indent) 297 throws NamingException 298 { 299 System.out.println(indent + syntaxElement); 300 Attributes entry = getAttributes(syntaxElement); 301 System.out.println(indent + "--==< " + syntaxElement + ">==--"); 302 if (entry == null) 303 System.out.println(indent + " ** NULL ENTRY **"); 304 else 305 { 306 NamingEnumeration atts = entry.getAll(); 307 while (atts.hasMoreElements()) 308 { 309 Attribute att = (Attribute) atts.nextElement(); 310 System.out.println(indent + "att " + att.getID()); 311 NamingEnumeration values = att.getAll(); 312 while (values.hasMoreElements()) 313 System.out.println(indent + " " + values.nextElement().toString()); 314 } 315 } 316 System.out.println(indent + "-"); 317 318 ArrayList list = listEntryNames(syntaxElement); 319 if (list == null) 320 { 321 return; 322 } 323 for (int i = 0; i < list.size(); i++) 324 { 325 String nextLevel = syntaxElement; 326 if (nextLevel.length() > 0) 327 nextLevel = "," + nextLevel; 328 nextLevel = "schema=" + list.get(i) + nextLevel; 329 tabbedDebugPrint(nextLevel, "\t" + indent); 330 } 331 } 332 333 public void printRawSchema() 334 { 335 if (rawSchemaAttributes == null) 336 { 337 System.out.println("NO SCHEMA READ!"); 338 return; 339 } 340 try 341 { 342 System.out.println("---RAW SCHEMA---"); 343 Enumeration attEnum = rawSchemaAttributes.getAll(); 344 while (attEnum.hasMoreElements()) 345 { 346 Attribute att = (Attribute) attEnum.nextElement(); 347 String ID = att.getID(); 348 Enumeration vals = att.getAll(); 349 while (vals.hasMoreElements()) 350 System.out.println(ID + " : " + vals.nextElement()); 351 } 352 } 353 catch (NamingException e) 354 { 355 System.out.println("error printing raw schema:" + e); 356 } 357 } 358 359 365 366 public Attributes getRawSchema() 368 throws NamingException 369 { 370 String rawSchemaRoot = getSchemaRoot(); 371 log.finest("reading raw schema from " + rawSchemaRoot); 372 Attributes rawSchema = null; 374 375 if (ctx != null) 376 rawSchema = ctx.getAttributes(rawSchemaRoot, new String []{"attributeTypes", "objectClasses", "matchingRules", "ldapSyntaxes", "*"}); 377 378 if (rawSchema == null) 379 { 380 log.warning("null schema read - returning empty schema list."); 381 rawSchema = new BasicAttributes(); } 383 else 384 { 385 if (rawSchema.size() == 0) { 387 log.warning("Unable to read schema details from directory."); 388 rawSchema = new BasicAttributes(); return rawSchema; 390 } 391 392 log.finest("some schema read..."); 393 394 395 rawSchema.remove("objectClass"); rawSchema.remove("oc"); rawSchema.remove("objectclass"); 398 String nameAttribute = rawSchemaRoot.substring(0, rawSchemaRoot.indexOf('=')); 399 rawSchema.remove(nameAttribute); 400 } 401 402 return rawSchema; 403 } 404 405 private void setSchemaRoot(String schema) 406 { 407 schemaRoot = schema; 408 } 409 410 415 416 public String getSchemaRoot() 417 { 418 if (schemaRoot != null) 419 return schemaRoot; 420 421 if (ctx != null) 422 { 423 try 424 { 425 log.finest("start get schema root call"); 426 Attributes SSSE; 427 SSSE = ctx.getAttributes("", new String []{subschemaAttributeName}); 428 if (SSSE != null && SSSE.get(subschemaAttributeName) != null) 429 schemaRoot = (String ) SSSE.get(subschemaAttributeName).get(); 430 431 log.finest("schema root read as being: '" + String.valueOf(schemaRoot) + "'"); 432 } 433 catch (NamingException e) 434 { 435 } 437 } 438 439 if (schemaRoot == null) 440 { 441 log.finest("forcing value of schema root to 'cn=schema', since can't read subschema attribute name"); 442 schemaRoot = "cn=schema"; } 444 return schemaRoot; 445 } 446 447 466 public Attributes getAttributes(String entryName) 467 throws NamingException 468 { 469 entryName = mangleEntryName(entryName); 470 471 BasicAttributes schemaAttributes = new BasicAttributes(); schemaAttributes.put(schemaObjectClassAttribute); 473 474 if (entryName == null || entryName.length() == 0) { 476 schemaAttributes.put(subschemaAttributeName, schemaRoot); 477 } 478 else if (entryName.indexOf(',') == -1 && entryName.indexOf('/') == -1) { 480 String schemaType = entryName.substring(entryName.indexOf('=') + 1); 481 schemaAttributes.put("schemaType", schemaType); 482 } 483 else 484 { 485 schemaAttributes = getAttributesFromSchemaName(entryName); 486 } 487 return schemaAttributes; 488 } 489 490 505 protected String mangleEntryName(String entryName) 506 { 507 if (entryName.indexOf("ClassDefinition") > -1) 508 entryName = entryName.replaceAll("(ClassDefinition)", "objectClasses"); 509 if (entryName.indexOf("SyntaxDefinition") > -1) 510 entryName = entryName.replaceAll("(SyntaxDefinition)", "ldapSyntaxes"); 511 if (entryName.indexOf("AttributeDefinition") > -1) 512 entryName = entryName.replaceAll("(AttributeDefinition)", "attributeTypes"); 513 514 if (entryName.indexOf('/') > 0) 516 { 517 int pos = entryName.indexOf(";binary"); 520 if (pos > -1) 521 entryName = entryName.substring(0, pos); 522 523 524 int slashpos = entryName.indexOf('/'); 525 String topLevelName = entryName.substring(0, slashpos); 526 String specificName = entryName.substring(++slashpos); 527 return "schema=" + specificName + ",schema=" + topLevelName; 528 } 529 530 532 int pos = entryName.indexOf(schemaRoot); 534 if (pos > 0) entryName = entryName.substring(0, pos - 1); 536 537 pos = entryName.indexOf("cn=schema"); 539 if (pos > 0) entryName = entryName.substring(0, pos - 1); 541 542 543 return entryName; 544 } 545 546 553 protected String getSpecificName(String entryName) 554 throws NamingException 555 { 556 int equalpos = entryName.indexOf('=') + 1; 557 int commapos = entryName.indexOf(','); 558 if (equalpos <= 0 || commapos == -1 || equalpos > commapos) 559 throw new NamingException ("error parsing schema dn '" + entryName + "' "); 560 561 return entryName.substring(equalpos, commapos); 562 } 563 564 571 572 protected String getTypeName(String entryName) 573 throws NamingException 574 { 575 if (entryName.endsWith(",cn=schema")) 576 entryName = entryName.substring(0, entryName.length() - 10); 577 578 int equalpos = entryName.lastIndexOf('=') + 1; 579 return entryName.substring(equalpos); 580 } 581 582 583 590 protected BasicAttributes getAttributesFromSchemaName(String entryName) throws NamingException 592 { 593 if (rawSchemaAttributes == null) 594 return null; 595 596 entryName = mangleEntryName(entryName); 597 598 String schemaTypeName = getTypeName(entryName); 600 String specificName = getSpecificName(entryName); 601 602 Attribute schemaGroup = rawSchemaAttributes.get(schemaTypeName); 603 604 if (schemaGroup == null) 605 { 606 schemaGroup = rawSchemaAttributes.get(schemaTypeName.toLowerCase()); 609 throw new NamingException ("Unable to find schema entry for schema type '" + schemaTypeName + "'"); 610 } 611 612 NamingEnumeration schemaValues = schemaGroup.getAll(); 613 String schemaValue; 614 while (schemaValues.hasMore()) 615 { 616 schemaValue = (String ) schemaValues.next(); 617 String [] names = getNames(schemaValue); 618 for (int i = 0; i < names.length; i++) 619 { 620 if (specificName.equalsIgnoreCase(names[i])) 622 { 623 return getAttributesFromSchemaValue(schemaValue); 624 } 625 } 626 } 627 return null; 628 } 629 630 640 642 649 private void addBracketedValues(Attribute schemaAttribute, StringTokenizer st) 650 { 651 while (st.hasMoreTokens()) 652 { 653 String token = st.nextToken(); 654 if (token.endsWith(")")) { 656 if (token.length() > 1) 657 schemaAttribute.add(getQuotedTokens(token.substring(0, token.length() - 1), st)); 658 659 return; 660 } 661 662 schemaAttribute.add(getQuotedTokens(token, st)); 663 } 664 } 665 666 673 private String getQuotedTokens(String token, StringTokenizer st) 674 { 675 if (token.charAt(0) != '\'') 676 return token; 677 678 if (token.length() < 2) return token; 680 681 if (token.charAt(0) == '\'' && token.charAt(token.length() - 1) == '\'') 682 return token.substring(1, token.length() - 1); 683 684 StringBuffer returnText = new StringBuffer (token.substring(1)); 686 while (st.hasMoreTokens()) 687 { 688 token = st.nextToken(); 689 if (token.endsWith("'")) 690 return (returnText.append(" ").append(token.substring(0, token.length() - 1)).toString()); 691 else 692 returnText.append(" ").append(token); 693 } 694 695 return returnText.toString(); } 697 698 699 706 protected BasicAttributes getAttributesFromSchemaValue(String syntaxValue) 707 { 708 BasicAttributes schemaValues = new BasicAttributes(); schemaValues.put(schemaObjectClassAttribute); 710 711 StringTokenizer st = new StringTokenizer(syntaxValue, " \t\n\r\f$"); 712 713 if (st.hasMoreTokens()) 715 { 716 String oid = st.nextToken(); 717 if (oid.startsWith("(")) { 719 if (oid.length() == 1) 720 oid = st.nextToken(); 721 else 722 oid = oid.substring(1); } 724 schemaValues.put(new BasicAttribute("OID", oid)); 725 } 726 727 while (st.hasMoreTokens()) 728 { 729 String attributeID = st.nextToken(); 730 if (attributeID.endsWith(")") == false) { 732 addAttribute(schemaValues, attributeID, st); 733 } 734 else 735 { 736 if (attributeID.length() > 1) 737 addAttribute(schemaValues, attributeID.substring(1), st); 738 } 739 } 740 741 try 742 { 743 Attribute syntaxOID; 744 if ((syntaxOID = schemaValues.get("SYNTAX")) != null) 745 { 746 String syntaxOIDString = (String )syntaxOID.get(); 747 String syntaxDescription = translateOID(syntaxOIDString); 748 schemaValues.put(new BasicAttribute("SYNTAX Description", syntaxDescription)); 749 } 750 } 751 catch (Exception e) 752 { 753 log.log(Level.INFO, "unable to translate syntax oid ", e); 754 } 755 return schemaValues; 756 } 757 758 766 767 private void addAttribute(Attributes schemaValues, String attributeName, StringTokenizer st) 768 { 769 BasicAttribute schemaAttribute = new BasicAttribute(attributeName); 770 schemaValues.put(schemaAttribute); 771 772 if (st.hasMoreTokens()) 773 { 774 String token = st.nextToken(); 775 if (token.startsWith("(")) 776 { 777 if (token.length() > 1) 778 { 779 if (token.endsWith(")") == true) { 781 token = token.substring(0, token.length() - 1); 782 schemaAttribute.add(token.substring(1)); 783 } 784 else 785 { 786 schemaAttribute.add(token.substring(1)); 787 addBracketedValues(schemaAttribute, st); 788 } 789 } 790 else 791 addBracketedValues(schemaAttribute, st); 792 } 793 else if (token.endsWith(")")) 794 { } 797 else if (isSyntaxKeyword(token) == true) 798 { 799 addAttribute(schemaValues, token, st); 800 } 801 else 802 { 803 token = getQuotedTokens(token, st); 804 schemaAttribute.add(token); 805 } 806 } 807 } 808 809 810 819 private static String readQuoteBlock(StringTokenizer st) 820 { 821 StringBuffer returnBuffer = new StringBuffer (); 822 823 while (st.hasMoreTokens()) 824 { 825 String token = st.nextToken(); 826 returnBuffer.append(" "); 827 returnBuffer.append(token); 828 if (token.endsWith("'")) 829 { 830 returnBuffer.deleteCharAt(returnBuffer.length() - 1); return returnBuffer.toString(); 832 } 833 } 834 log.finest("unexpected end of schema text in single quoted block"); 835 return returnBuffer.toString(); 836 } 837 838 845 private static boolean isSyntaxKeyword(String token) 846 { 847 String [] reservedKeywords = { 848 "ABSTRACT", 849 "APPLIES", 850 "AUXILIARY", 851 "COLLECTIVE", 852 "DESC", 853 "EQUALITY", 854 "MAY", 855 "MUST", 856 "NAME", 857 "NO-USER-MODIFICATION", 858 "OBSOLETE", 859 "ORDERING", 860 "SINGLE-VALUE", 861 "STRUCTURAL", 862 "SUBSTR", 863 "SUP", 864 "SYNTAX", 865 "USAGE"}; 866 867 int size = reservedKeywords.length; 868 for (int i = 0; i < size; i++) 869 if (reservedKeywords[i].equals(token)) 870 return true; 871 872 if (token.startsWith("X-")) 873 return true; 874 875 return false; } 877 888 889 899 public ArrayList listEntryNames(String entryName) 900 throws NamingException 901 { 902 if (rawSchemaAttributes == null) 903 return new ArrayList(); 904 905 entryName = mangleEntryName(entryName); 906 907 ArrayList schemaNames; 908 909 if (entryName == null || entryName.length() == 0 || entryName.equals("cn=schema") || entryName.equals(schemaRoot)) { schemaNames = new ArrayList(10); 912 Enumeration schemaTopLevelNames = rawSchemaAttributes.getIDs(); 913 while (schemaTopLevelNames.hasMoreElements()) 914 { 915 String name = (String ) schemaTopLevelNames.nextElement(); 916 if (!schemaNames.contains(name)) schemaNames.add(name); 918 } 919 } 920 else if (entryName.indexOf(',') == -1 && entryName.indexOf('/') == -1) { schemaNames = new ArrayList(1000); 923 if (entryName.indexOf('=') > 0) 924 entryName = entryName.substring(entryName.indexOf('=') + 1); 925 Attribute rawSyntaxAttribute = rawSchemaAttributes.get(entryName); if (rawSyntaxAttribute == null) 927 throw new NamingException ("unable to list syntaxes of type '" + entryName + "'"); 928 929 Enumeration values = rawSyntaxAttribute.getAll(); 930 String [] names; 931 while (values.hasMoreElements()) 932 { 933 names = getNames((String ) values.nextElement()); 934 for (int i = 0; i < names.length; i++) 935 { 936 if (!schemaNames.contains(names[i])) schemaNames.add(names[i]); 938 } 939 } 940 } 941 else { 943 schemaNames = new ArrayList(0); 944 } 945 946 return schemaNames; 947 } 948 949 950 private int name_pos, bracket_pos, quote_pos, last_pos, pos; 953 960 962 public final String getOID(String ldapSchemaDescription) 963 { 964 if (ldapSchemaDescription == null) 965 return "0"; 967 int start = 0; 968 969 if (ldapSchemaDescription.charAt(0) == '(') 970 start++; 971 972 while (ldapSchemaDescription.charAt(start) == ' ') start++; 974 975 try 976 { 977 int endpos = ldapSchemaDescription.indexOf(' ', start); 978 if (endpos == -1) 979 endpos = ldapSchemaDescription.indexOf(')', start); 980 if (endpos == -1) 981 endpos = ldapSchemaDescription.length(); 982 983 String ret = ldapSchemaDescription.substring(start, endpos); 984 return ret; 985 } 986 catch (Exception e) 987 { 988 log.log(Level.WARNING, "can't parse '" + ldapSchemaDescription + "'"); 989 e.printStackTrace(); 990 return "0"; 991 } 992 } 993 994 1001 1002 1004 public final String getFirstName(String ldapSchemaDescription) 1005 { 1006 name_pos = ldapSchemaDescription.indexOf("NAME"); 1007 if (name_pos == -1) 1008 name_pos = ldapSchemaDescription.indexOf("DESC"); if (name_pos == -1) { 1011 if (ldapSchemaDescription.startsWith("{")) 1012 ldapSchemaDescription = ldapSchemaDescription.substring(1).trim(); 1013 pos = ldapSchemaDescription.indexOf(' '); 1014 if (pos == -1) 1015 { 1016 log.log(Level.WARNING, "unable to get name from " + ldapSchemaDescription); 1017 return "syntax_error"; 1018 } 1019 return ldapSchemaDescription.substring(0, pos).trim(); 1020 } 1021 quote_pos = ldapSchemaDescription.indexOf('\'', name_pos); 1022 quote_pos++; 1023 last_pos = ldapSchemaDescription.indexOf('\'', quote_pos); 1024 if (quote_pos != 0 && last_pos != -1) 1025 return ldapSchemaDescription.substring(quote_pos, last_pos); 1026 else 1027 { 1028 log.log(Level.WARNING, "unable to parse " + ldapSchemaDescription); 1029 return "syntax_error"; 1030 } 1031 1032 } 1033 1034 1041 1043 public final String [] getNames(String ldapSyntaxDescription) 1044 { 1045 try 1046 { 1047 name_pos = ldapSyntaxDescription.indexOf("NAME"); 1048 if (name_pos == -1) 1049 name_pos = ldapSyntaxDescription.indexOf("DESC"); if (name_pos == -1) { 1052 if (ldapSyntaxDescription.startsWith("{")) 1053 ldapSyntaxDescription = ldapSyntaxDescription.substring(1).trim(); 1054 return new String []{ldapSyntaxDescription.substring(0, ldapSyntaxDescription.indexOf(' ')).trim()}; 1055 } 1056 1057 bracket_pos = ldapSyntaxDescription.indexOf('(', name_pos); 1058 quote_pos = ldapSyntaxDescription.indexOf('\'', name_pos); 1059 1060 if (bracket_pos != -1 && bracket_pos < quote_pos) { 1062 bracket_pos = ldapSyntaxDescription.indexOf(')', bracket_pos); ArrayList newList = new ArrayList(5); 1064 while (quote_pos < bracket_pos && quote_pos != -1) { 1066 int start = ++quote_pos; 1067 quote_pos = ldapSyntaxDescription.indexOf('\'', quote_pos); 1068 1069 String temp = ldapSyntaxDescription.substring(start, quote_pos); 1070 newList.add(temp); 1071 1072 quote_pos++; 1073 quote_pos = ldapSyntaxDescription.indexOf('\'', quote_pos); 1074 } 1075 return (String []) newList.toArray(new String []{}); 1076 } 1077 else { 1079 quote_pos++; 1080 int next_quote = ldapSyntaxDescription.indexOf('\'', quote_pos); 1081 String temp = ldapSyntaxDescription.substring(quote_pos, next_quote); 1082 return new String []{temp}; 1083 } 1084 } 1085 catch (StringIndexOutOfBoundsException e) 1086 { 1087 log.log(Level.WARNING, "unable to parse line: " + ldapSyntaxDescription, e); 1088 return new String []{"syntax_error"}; 1089 } 1090 } 1091 1092 1093 1097 1117 1118 1124 public ArrayList objectClasses() 1125 throws NamingException 1126 { 1127 if (fullObjectClassArray == null) 1128 { 1129 ArrayList temp = listEntryNames("schema=objectClasses,cn=schema"); 1130 if (temp == null) 1131 throw new NamingException ("unable to read list of object classes from schema"); 1132 String [] OCs = (String []) temp.toArray(new String [temp.size()]); 1133 Arrays.sort(OCs, new Comparator() 1134 { 1135 public int compare(Object a, Object b) 1136 { 1137 return ((String ) a).compareToIgnoreCase((String ) b); 1138 } 1139 1140 public boolean equals(Object a, Object b) 1141 { 1142 return ((String ) a).equalsIgnoreCase((String ) b); 1143 } 1144 }); 1145 int size = OCs.length; 1146 fullObjectClassArray = new ArrayList(size); 1147 for (int i = 0; i < size; i++) 1148 fullObjectClassArray.add(i, OCs[i]); 1149 } 1150 1151 return fullObjectClassArray; 1152 } 1153 1154 1155 1161 public ArrayList attributeNames() 1162 throws NamingException 1163 { 1164 if (fullAttributeNameArray == null) 1165 { 1166 ArrayList temp = listEntryNames("schema=attributeTypes,cn=schema"); 1167 if (temp == null) 1168 throw new NamingException ("unable to read list of attribute types from schema"); 1169 String [] ATs = (String []) temp.toArray(new String [temp.size()]); 1170 Arrays.sort(ATs, new Comparator() 1171 { 1172 public int compare(Object a, Object b) 1173 { 1174 return ((String ) a).compareToIgnoreCase((String ) b); 1175 } 1176 1177 public boolean equals(Object a, Object b) 1178 { 1179 return ((String ) a).equalsIgnoreCase((String ) b); 1180 } 1181 }); 1182 int size = ATs.length; 1183 fullAttributeNameArray = new ArrayList(size); 1184 for (int i = 0; i < size; i++) 1185 fullAttributeNameArray.add(i, ATs[i]); 1186 } 1187 1188 return fullAttributeNameArray; 1189 } 1190 1191 1199 1200 public ArrayList getRecommendedObjectClasses(String dn) 1201 { 1202 try 1203 { 1204 if ((dn != null) && ctx != null) 1205 { 1206 Attributes atts = ctx.getAttributes(dn); 1207 1208 if (atts == null) 1209 { 1210 log.log(Level.WARNING, "error reading object classes for " + dn); 1211 } 1212 else 1213 { 1214 Attribute objectClasses = atts.get("objectclass"); 1215 if (objectClasses == null) objectClasses = atts.get("objectClass"); 1217 if (objectClasses == null) objectClasses = atts.get("oc"); 1219 1220 if (objectClasses == null) { 1222 log.log(Level.WARNING, "unable to recognize object classes for " + dn); 1223 } 1224 else 1225 { 1226 NamingEnumeration names = objectClasses.getAll(); 1227 if (names == null) 1228 log.log(Level.WARNING, "object class has no attributes!"); 1229 1230 ArrayList returnArray = new ArrayList(10); 1231 while (names.hasMore()) 1232 returnArray.add(names.next()); 1233 1234 return returnArray; 1235 } 1236 } 1237 } 1238 } 1239 catch (NamingException e) 1240 { 1241 log.log(Level.WARNING, "error reading object classes for " + dn + "\n internal error III: ", e); 1242 } 1243 return null; 1244 } 1245 1246 1247 1254 public String getNewBinaryAttributes() 1256 { 1257 if (rawSchemaAttributes == null) 1258 return ""; 1259 1260 try 1261 { 1262 StringBuffer binaryAttributeList = new StringBuffer (1000); 1263 Attribute rawSyntaxAttribute = getAttributeTypes(); 1264 if (rawSyntaxAttribute == null) 1265 return ""; 1266 1267 NamingEnumeration values = rawSyntaxAttribute.getAll(); 1268 while (values.hasMore()) 1269 { 1270 String attributeDescription = (String ) values.next(); if ((attributeDescription.indexOf("1.3.6.1.4.1.1466.115.121.1.5 ") > 0) || (attributeDescription.indexOf("1.3.6.1.4.1.1466.115.121.1.40") > 0) || (attributeDescription.indexOf("1.3.6.1.4.1.1466.115.121.1.28") > 0) || (attributeDescription.indexOf("1.3.6.1.4.1.1466.115.121.1.8") > 0)) { 1276 String [] names = getNames(attributeDescription); 1277 for (int i = 0; i < names.length; i++) 1278 { 1279 binaryAttributeList.append(names[i]); 1280 binaryAttributeList.append(' '); 1281 } 1282 } 1283 } 1284 return binaryAttributeList.toString(); 1285 } 1286 catch (NamingException e) 1287 { 1288 log.log(Level.WARNING, "unable to get binary attributes from schema", e); 1289 return ""; 1290 } 1291 1292 } 1293 1294 1302 1303 public Attribute getAttributeTypes() 1304 { 1305 return rawSchemaAttributes.get("attributeTypes"); 1306 } 1307 1308 1314 public String getAttributeSyntax(String attID) 1315 { 1316 if(attID == null) 1317 return null; 1318 1319 if (attID.indexOf(';') > 0) 1320 attID = attID.substring(0, attID.indexOf(';')); 1322 return schemaLookup("schema=" + attID + ",schema=attributeTypes", "SYNTAX"); 1323 } 1324 1325 1332 1333 public String schemaLookup(String entryName, String schemaAttribute) 1334 { 1335 entryName = mangleEntryName(entryName); 1336 1337 try 1338 { 1339 Attributes schemaAtts = getAttributes(entryName); 1340 Attribute schemaAtt = schemaAtts.get(schemaAttribute); 1341 String att = (String ) schemaAtt.get(); 1342 return att; 1343 1344 } 1345 catch (NamingException e) 1346 { 1347 log.log(Level.WARNING, "unable to get value for " + entryName + " value: " + schemaAttribute, e); 1348 } 1349 catch (NullPointerException e2) 1350 { 1351 if ("DESC".equals(schemaAttribute) == false) log.log(Level.WARNING, "unable to read any schema entry for " + entryName + "and attribute: " + schemaAttribute, e2); 1353 } 1354 catch (NoSuchElementException e) 1355 { 1356 if ("DESC".equals(schemaAttribute) == false) log.log(Level.WARNING, "unable to read any schema entry for " + entryName + "and attribute: " + schemaAttribute, e); 1358 } 1359 return null; 1360 } 1361 1362 public String getNameOfObjectClassAttribute() 1363 { 1364 return schemaLookup("schema=objectClass,schema=attributeTypes", "NAME"); 1365 } 1366 1367 1368 1382 1383 public boolean isAttributeSingleValued(String name) 1384 { 1385 if (rawSchemaAttributes == null) 1386 return false; 1387 1388 try 1389 { 1390 Attribute attributeTypes = getAttributeTypes(); 1391 NamingEnumeration en = attributeTypes.getAll(); 1392 1393 while (en.hasMore()) 1394 { 1395 String attr = (String ) en.next(); 1396 String [] attrName = getNames(attr); 1397 1398 for (int i = 0; i < attrName.length; i++) 1399 if (attrName[i].equals(name) && (attr.indexOf("SINGLE-VALUE") >= 0)) 1400 return true; 1401 } 1402 } 1403 catch (NamingException e) 1404 { 1405 log.log(Level.WARNING, "Unable to determine if attribute '" + name + "' is SINGLE-VALUE." + e); 1406 } 1407 return false; 1408 } 1409} 1410 | Popular Tags |