1 package com.ca.jndiproviders.dsml; 2 3 import junit.framework.*; 4 5 import javax.naming.NamingException ; 6 import javax.naming.NamingEnumeration ; 7 import javax.naming.directory.*; 8 import java.util.*; 9 import java.io.*; 10 11 import com.ca.commons.naming.DXNamingEnumeration; 12 13 16 public class DsmlContextTest extends TestCase 17 { 18 21 public DsmlContextTest(String name) 22 { 23 super(name); 24 } 25 26 29 public static Test suite() 30 { 31 return new TestSuite(DsmlContextTest.class); 32 } 33 34 37 public static void main(String [] args) 38 { 39 junit.textui.TestRunner.run(suite()); 40 } 41 42 45 public void testModifyRequest() 46 throws Exception 47 { 48 } 50 51 54 public void testSearchTreeRequest() 55 throws Exception 56 { 57 StringBuffer treeSearch = DsmlContext.constructSearchRequest("c=AU", "wholeSubtree", "neverDerefAliases", 0, 0, false, "(objectClass=*)", new String []{"objectClass", "cn"}); 58 assertXMLEquals(searchRequestSubTree, treeSearch.toString()); 59 60 } 64 65 68 public void testSearchLevelRequest() 69 throws Exception 70 { 71 StringBuffer levelSearch = DsmlContext.constructSearchRequest("c=AU", "singleLevel", "derefInSearching", 0, 0, false, "(objectClass=*)", new String []{"objectClass", "cn"}); 72 74 } 78 79 82 public void testSearchEntry() 83 throws Exception 84 { 85 StringBuffer entrySearch = DsmlContext.constructSearchRequest("c=AU", "baseObject", "derefAlways", 0, 0, false, "(objectClass=*)", null); 86 88 } 92 93 94 private static String searchResponse1 = "" + 95 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 96 " <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> \n" + 97 " <soapenv:Body>\n" + 98 " <batchResponse xmlns=\"urn:oasis:names:tc:DSML:2:0:core\">\n" + 99 " <searchResponse>\n" + 100 " <searchResultEntry dn=\"ou=Corporate,o=DEMOCORP,c=AU\">\n" + 101 " <attr name=\"ou\">\n" + 102 " <value>Corporate</value>\n" + 103 " </attr>\n" + 104 " <attr name=\"objectClass\">\n" + 105 " <value>organizationalUnit</value>\n" + 106 " <value>top</value>\n" + 107 " <value>inetOrganizationalUnit</value>\n" + 108 " </attr>\n" + 109 " <attr name=\"description\">\n" + 110 " <value>a very nice org unit</value>\n" + 111 " <value>not at all like sales</value>\n" + 112 " <value>no charges were ever proved</value>\n" + 113 " <value>Clerical </value> fred</value>\n" + 114 " </attr>\n" + 115 " <attr name=\"password\">\n" + 116 " <value xsi:type=\"xsd:base64Binary\">YQBh</value> " + 117 " </attr>\n" + 118 " </searchResultEntry>\n" + 119 " <searchResultEntry dn=\"ou=Customer,o=DEMOCORP,c=AU\">\n" + 120 " <attr name=\"ou\">\n" + 121 " <value>Customer</value>\n" + 122 " </attr>\n" + 123 " <attr name=\"objectClass\">\n" + 124 " <value>organizationalUnit</value>\n" + 125 " </attr>\n" + 126 " </searchResultEntry>\n" + 127 " <searchResultEntry dn=\"ou=Engineering,o=DEMOCORP,c=AU\">\n" + 128 " <attr name=\"ou\">\n" + 129 " <value>Engineering</value>\n" + 130 " </attr>\n" + 131 " <attr name=\"objectClass\">\n" + 132 " <value>organizationalUnit</value>\n" + 133 " </attr>\n" + 134 " </searchResultEntry>\n" + 135 " <searchResultEntry dn=\"ou=Human Resources,o=DEMOCORP,c=AU\">\n" + 136 " <attr name=\"ou\">\n" + 137 " <value>Human Resources</value>\n" + 138 " </attr>\n" + 139 " <attr name=\"objectClass\">\n" + 140 " <value>organizationalUnit</value>\n" + 141 " </attr>\n" + 142 " </searchResultEntry>\n" + 143 " <searchResultEntry dn=\"ou=Manufacturing,o=DEMOCORP,c=AU\">\n" + 144 " <attr name=\"ou\">\n" + 145 " <value>Manufacturing</value>\n" + 146 " </attr>\n" + 147 " <attr name=\"objectClass\">\n" + 148 " <value>organizationalUnit</value>\n" + 149 " </attr>\n" + 150 " </searchResultEntry>\n" + 151 " <searchResultEntry dn=\"ou=Marketing,o=DEMOCORP,c=AU\">\n" + 152 " <attr name=\"ou\">\n" + 153 " <value>Marketing</value>\n" + 154 " </attr>\n" + 155 " <attr name=\"objectClass\">\n" + 156 " <value>organizationalUnit</value>\n" + 157 " </attr>\n" + 158 " </searchResultEntry>\n" + 159 " <searchResultEntry dn=\"ou=Operations,o=DEMOCORP,c=AU\">\n" + 160 " <attr name=\"ou\">\n" + 161 " <value>Operations</value>\n" + 162 " </attr>\n" + 163 " <attr name=\"objectClass\">\n" + 164 " <value>organizationalUnit</value>\n" + 165 " <value>top</value>\n" + 166 " <value>inetOrganizationalUnit</value>\n" + 167 " </attr>\n" + 168 " </searchResultEntry>\n" + 169 " <searchResultEntry dn=\"ou=Planning,o=DEMOCORP,c=AU\">\n" + 170 " <attr name=\"ou\">\n" + 171 " <value>Planning</value>\n" + 172 " </attr>\n" + 173 " <attr name=\"objectClass\">\n" + 174 " <value>organizationalUnit</value>\n" + 175 " </attr>\n" + 176 " </searchResultEntry>\n" + 177 " <searchResultEntry dn=\"ou=Projects,o=DEMOCORP,c=AU\">\n" + 178 " <attr name=\"ou\">\n" + 179 " <value>Projects</value>\n" + 180 " </attr>\n" + 181 " <attr name=\"objectClass\">\n" + 182 " <value>organizationalUnit</value>\n" + 183 " </attr>\n" + 184 " </searchResultEntry>\n" + 185 " <searchResultEntry dn=\"ou=Services,o=DEMOCORP,c=AU\">\n" + 186 " <attr name=\"ou\">\n" + 187 " <value>Services</value>\n" + 188 " </attr>\n" + 189 " <attr name=\"objectClass\">\n" + 190 " <value>organizationalUnit</value>\n" + 191 " </attr>\n" + 192 " </searchResultEntry>\n" + 193 " <searchResultEntry dn=\"ou=\\\"Support\\\",o=DEMOCORP,c=AU\">\n" + 194 " <attr name=\"ou\">\n" + 195 " <value>Support</value>\n" + 196 " </attr>\n" + 197 " <attr name=\"objectClass\">\n" + 198 " <value>organizationalUnit</value>\n" + 199 " </attr>\n" + 200 " </searchResultEntry>\n" + 201 " <searchResultDone>\n" + 202 " <resultCode code=\"0\"/>\n" + 203 " </searchResultDone>\n" + 204 " </searchResponse>\n" + 205 " </batchResponse> \n" + 206 " </soapenv:Body>\n" + 207 " </soapenv:Envelope>"; 208 209 210 private static String searchResponse2 = "" + 211 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 212 " <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"> \n" + 213 " <mydsml:soapenv:Body>\n" + 214 " <mydsml:batchResponse xmlns:mydsml=\"urn:oasis:names:tc:DSML:2:0:core\">\n" + 215 " <mydsml:searchResponse>\n" + 216 " <mydsml:searchResultEntry dn=\"ou=Corporate,o=DEMOCORP,c=AU\">\n" + 217 " <mydsml:attr name=\"ou\">\n" + 218 " <mydsml:value>Corporate</mydsml:value>\n" + 219 " </mydsml:attr>\n" + 220 " <mydsml:attr name=\"objectClass\">\n" + 221 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 222 " <mydsml:value>top</mydsml:value>\n" + 223 " <mydsml:value>inetOrganizationalUnit</mydsml:value>\n" + 224 " </mydsml:attr>\n" + 225 " <mydsml:attr name=\"description\">\n" + 226 " <mydsml:value>a very nice org unit</mydsml:value>\n" + 227 " <mydsml:value>not at all like sales</mydsml:value>\n" + 228 " <mydsml:value>no charges were ever proved</mydsml:value>\n" + 229 " <mydsml:value>Clerical </value> fred</mydsml:value>\n" + 230 " </mydsml:attr>\n" + 231 " <mydsml:attr name=\"password\">\n" + 232 " <mydsml:value xsi:type=\"xsd:base64Binary\">YQBh</mydsml:value> " + 233 " </mydsml:attr>\n" + 234 " </mydsml:searchResultEntry>\n" + 235 " <mydsml:searchResultEntry dn=\"ou=Customer,o=DEMOCORP,c=AU\">\n" + 236 " <mydsml:attr name=\"ou\">\n" + 237 " <mydsml:value>Customer</mydsml:value>\n" + 238 " </mydsml:attr>\n" + 239 " <mydsml:attr name=\"objectClass\">\n" + 240 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 241 " </mydsml:attr>\n" + 242 " </mydsml:searchResultEntry>\n" + 243 " <mydsml:searchResultEntry dn=\"ou=Engineering,o=DEMOCORP,c=AU\">\n" + 244 " <mydsml:attr name=\"ou\">\n" + 245 " <mydsml:value>Engineering</mydsml:value>\n" + 246 " </mydsml:attr>\n" + 247 " <mydsml:attr name=\"objectClass\">\n" + 248 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 249 " </mydsml:attr>\n" + 250 " </mydsml:searchResultEntry>\n" + 251 " <mydsml:searchResultEntry dn=\"ou=Human Resources,o=DEMOCORP,c=AU\">\n" + 252 " <mydsml:attr name=\"ou\">\n" + 253 " <mydsml:value>Human Resources</mydsml:value>\n" + 254 " </mydsml:attr>\n" + 255 " <mydsml:attr name=\"objectClass\">\n" + 256 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 257 " </mydsml:attr>\n" + 258 " </mydsml:searchResultEntry>\n" + 259 " <mydsml:searchResultEntry dn=\"ou=Manufacturing,o=DEMOCORP,c=AU\">\n" + 260 " <mydsml:attr name=\"ou\">\n" + 261 " <mydsml:value>Manufacturing</mydsml:value>\n" + 262 " </mydsml:attr>\n" + 263 " <mydsml:attr name=\"objectClass\">\n" + 264 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 265 " </mydsml:attr>\n" + 266 " </mydsml:searchResultEntry>\n" + 267 " <mydsml:searchResultEntry dn=\"ou=Marketing,o=DEMOCORP,c=AU\">\n" + 268 " <mydsml:attr name=\"ou\">\n" + 269 " <mydsml:value>Marketing</mydsml:value>\n" + 270 " </mydsml:attr>\n" + 271 " <mydsml:attr name=\"objectClass\">\n" + 272 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 273 " </mydsml:attr>\n" + 274 " </mydsml:searchResultEntry>\n" + 275 " <mydsml:searchResultEntry dn=\"ou=Operations,o=DEMOCORP,c=AU\">\n" + 276 " <mydsml:attr name=\"ou\">\n" + 277 " <mydsml:value>Operations</mydsml:value>\n" + 278 " </mydsml:attr>\n" + 279 " <mydsml:attr name=\"objectClass\">\n" + 280 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 281 " <mydsml:value>top</mydsml:value>\n" + 282 " <mydsml:value>inetOrganizationalUnit</mydsml:value>\n" + 283 " </mydsml:attr>\n" + 284 " </mydsml:searchResultEntry>\n" + 285 " <mydsml:searchResultEntry dn=\"ou=Planning,o=DEMOCORP,c=AU\">\n" + 286 " <mydsml:attr name=\"ou\">\n" + 287 " <mydsml:value>Planning</mydsml:value>\n" + 288 " </mydsml:attr>\n" + 289 " <mydsml:attr name=\"objectClass\">\n" + 290 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 291 " </mydsml:attr>\n" + 292 " </mydsml:searchResultEntry>\n" + 293 " <mydsml:searchResultEntry dn=\"ou=Projects,o=DEMOCORP,c=AU\">\n" + 294 " <mydsml:attr name=\"ou\">\n" + 295 " <mydsml:value>Projects</mydsml:value>\n" + 296 " </mydsml:attr>\n" + 297 " <mydsml:attr name=\"objectClass\">\n" + 298 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 299 " </mydsml:attr>\n" + 300 " </mydsml:searchResultEntry>\n" + 301 " <mydsml:searchResultEntry dn=\"ou=Services,o=DEMOCORP,c=AU\">\n" + 302 " <mydsml:attr name=\"ou\">\n" + 303 " <mydsml:value>Services</mydsml:value>\n" + 304 " </mydsml:attr>\n" + 305 " <mydsml:attr name=\"objectClass\">\n" + 306 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 307 " </mydsml:attr>\n" + 308 " </mydsml:searchResultEntry>\n" + 309 " <mydsml:searchResultEntry dn=\"ou=\\\"Support\\\",o=DEMOCORP,c=AU\">\n" + 310 " <mydsml:attr name=\"ou\">\n" + 311 " <mydsml:value>Support</mydsml:value>\n" + 312 " </mydsml:attr>\n" + 313 " <mydsml:attr name=\"objectClass\">\n" + 314 " <mydsml:value>organizationalUnit</mydsml:value>\n" + 315 " </mydsml:attr>\n" + 316 " </mydsml:searchResultEntry>\n" + 317 " <mydsml:searchResultDone requestID=\"1\">\n" + 318 " <mydsml:resultCode code=\"0\"/>\n" + 319 " </mydsml:searchResultDone>\n" + 320 " </mydsml:searchResponse>\n" + 321 " </mydsml:batchResponse> \n" + 322 " </soapenv:Body>\n" + 323 " </soapenv:Envelope>"; 324 325 326 public void testSearchResultParse() 327 throws NamingException 328 { 329 NamingEnumeration results1 = DsmlContext.parseSearchResponse(searchResponse1, "c=AU"); 330 331 333 SearchResult result = (SearchResult) results1.next(); 334 335 String dn = result.getName(); 336 337 assertEquals(dn, "ou=Corporate,o=DEMOCORP,c=AU"); 338 339 OrderedAttributes atts = new OrderedAttributes(result.getAttributes()); 340 341 Enumeration attEnum = atts.getAll(); 342 343 Attribute att1 = (Attribute) attEnum.nextElement(); 344 345 assertEquals(att1.getID(), "description"); 346 347 Enumeration values = att1.getAll(); 348 349 assertEquals(values.nextElement(), "a very nice org unit"); 350 assertEquals(values.nextElement(), "not at all like sales"); 351 assertEquals(values.nextElement(), "no charges were ever proved"); 352 assertEquals(values.nextElement(), "Clerical </value> fred"); 353 354 355 } 356 357 358 private static String searchRequestSubTree = "" + 359 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 360 " <soap-env:Envelope xmlns:soap-env=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" + 361 " <soap-env:Body>\n" + 362 " <dsml:batchRequest xmlns:dsml=\"urn:oasis:names:tc:DSML:2:0:core\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" + 363 " <dsml:searchRequest dn=\"c=AU\" scope=\"wholeSubtree\" derefAliases=\"neverDerefAliases\">\n" + 364 " <dsml:filter>\n" + 365 " <dsml:present name=\"objectClass\"/>\n" + 366 " </dsml:filter>\n" + 367 " <dsml:attributes>\n" + 368 " <dsml:attribute name=\"objectClass\"/>\n" + 369 " <dsml:attribute name=\"cn\"/>\n" + 370 " </dsml:attributes>\n" + 371 " </dsml:searchRequest>\n" + 372 " </dsml:batchRequest>\n" + 373 " </soap-env:Body>\n" + 374 " </soap-env:Envelope>"; 375 376 379 private static String searchRequest1 = 380 "<dsml:batchRequest xmlns:dsml=\"urn:oasis:names:tc:DSML:2:0:core\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + 381 " <dsml:searchRequest dn=\"c=AU\" scope=\"wholeSubtree\" derefAliases=\"neverDerefAliases\">" + 382 " <dsml:filter>" + 383 " <dsml:equalityMatch name=\"cn\">" + 384 " <dsml:value>Trudi</dsml:value>" + 385 " </dsml:equalityMatch>" + 386 " </dsml:filter>" + 387 " <dsml:attributes>" + 388 " <dsml:attribute name=\"objectClass\"/>" + 389 " </dsml:attributes>" + 390 " </dsml:searchRequest>" + 391 "</dsml:batchRequest>"; 392 393 396 private static String searchRequest2 = 397 "<dsml:batchRequest xmlns:dsml=\"urn:oasis:names:tc:DSML:2:0:core\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + 398 " <dsml:searchRequest requestID=\"101\" dn=\"c=AU\" scope=\"wholeSubtree\" derefAliases=\"neverDerefAliases\">" + 399 " <dsml:filter>" + 400 " <dsml:and>" + 401 " <dsml:or>" + 402 " <dsml:substrings name=\"sn\">" + 403 " <dsml:initial>z</dsml:initial>" + 404 " </dsml:substrings>" + 405 " <dsml:substrings name=\"sn\">" + 406 " <dsml:initial>w</dsml:initial>" + 407 " </dsml:substrings>" + 408 " </dsml:or>" + 409 " <dsml:or>" + 410 " <dsml:substrings name=\"sn\">" + 411 " <dsml:initial>e</dsml:initial>" + 412 " </dsml:substrings>" + 413 " <dsml:substrings name=\"sn\">" + 414 " <dsml:initial>r</dsml:initial>" + 415 " </dsml:substrings>" + 416 " </dsml:or>" + 417 " </dsml:and>" + 418 " </dsml:filter>" + 419 " <dsml:attributes>" + 420 " <dsml:attribute name=\"objectClass\"/>" + 421 " </dsml:attributes>" + 422 " </dsml:searchRequest>" + 423 "</dsml:batchRequest>"; 424 425 430 public void testLdapFilter() 431 throws NamingException 432 { 433 assertXMLEquals(filter1, DsmlContext.getSearchRequestFilter(new StringBuffer (), "(cn=fred)", " ")); 434 435 assertXMLEquals(filter2, DsmlContext.getSearchRequestFilter(new StringBuffer (), "(&(!(sn<=Le*))(cn~=Crai))", " ")); 436 437 assertXMLEquals(filter3, DsmlContext.getSearchRequestFilter(new StringBuffer (), "(!(|(&(!(|(sn=*)(cn=a*)(sn=b)))(!(&(sn=*c)(!(cn=d*))(sn=*e*))))(|(!(sn=f))(cn=g)(cn=*a*b*c*)(!(sn=*h)))))", " ")); 438 } 439 440 443 public void testCreateAttributeLdapFilter() 444 { 445 OrderedAttributes testAtts = new OrderedAttributes("person", "chris"); 446 447 assertEquals("(person=*)", DsmlContext.getAttributeMatchFilter(testAtts)); 448 449 testAtts.put(new BasicAttribute("favoriteDrink")); 450 451 assertEquals("(&(favoriteDrink=*)(person=*))", DsmlContext.getAttributeMatchFilter(testAtts)); 452 453 testAtts.put(new BasicAttribute("postCode")); 454 455 assertEquals("(&(favoriteDrink=*)(person=*)(postCode=*))", DsmlContext.getAttributeMatchFilter(testAtts)); 456 457 testAtts.put(new BasicAttribute("address")); 458 testAtts.put(new BasicAttribute("uid")); 459 460 assertEquals("(&(address=*)(favoriteDrink=*)(person=*)(postCode=*)(uid=*))", DsmlContext.getAttributeMatchFilter(testAtts)); 461 462 assertEquals("(objectClass=*)", DsmlContext.getAttributeMatchFilter(new BasicAttributes())); 463 464 assertEquals("(objectClass=*)", DsmlContext.getAttributeMatchFilter(null)); 465 } 466 467 private static String filter1 = 468 "<dsml:filter>\n" + 469 " <dsml:equalityMatch name=\"cn\">\n" + 470 " <dsml:value>fred</dsml:value>\n" + 471 " </dsml:equalityMatch>\n" + 472 "</dsml:filter>"; 473 474 private static String filter2 = 475 " <dsml:filter>\n" + 476 " <dsml:and>\n" + 477 " <dsml:not>\n" + 478 " <dsml:lessOrEqual name=\"sn\">\n" + 479 " <dsml:value>Le*</dsml:value>\n" + 480 " </dsml:lessOrEqual>\n" + 481 " </dsml:not>\n" + 482 " <dsml:approxMatch name=\"cn\">\n" + 483 " <dsml:value>Crai</dsml:value>\n" + 484 " </dsml:approxMatch>\n" + 485 " </dsml:and>\n" + 486 " </dsml:filter>"; 487 490 private static String filter3 = 491 " <dsml:filter>" + 492 " <dsml:not>" + 493 " <dsml:or>" + 494 " <dsml:and>" + 495 " <dsml:not>" + 496 " <dsml:or>" + 497 " <dsml:present name=\"sn\"/>" + 498 " <dsml:substrings name=\"cn\">" + 499 " <dsml:initial>a</dsml:initial>" + 500 " </dsml:substrings>" + 501 " <dsml:equalityMatch name=\"sn\">" + 502 " <dsml:value>b</dsml:value>" + 503 " </dsml:equalityMatch>" + 504 " </dsml:or>" + 505 " </dsml:not>" + 506 " <dsml:not>" + 507 " <dsml:and>" + 508 " <dsml:substrings name=\"sn\">" + 509 " <dsml:final>c</dsml:final>" + 510 " </dsml:substrings>" + 511 " <dsml:not>" + 512 " <dsml:substrings name=\"cn\">" + 513 " <dsml:initial>d</dsml:initial>" + 514 " </dsml:substrings>" + 515 " </dsml:not>" + 516 " <dsml:substrings name=\"sn\">" + 517 " <dsml:any>e</dsml:any>" + 518 " </dsml:substrings>" + 519 " </dsml:and>" + 520 " </dsml:not>" + 521 " </dsml:and>" + 522 " <dsml:or>" + 523 " <dsml:not>" + 524 " <dsml:equalityMatch name=\"sn\">" + 525 " <dsml:value>f</dsml:value>" + 526 " </dsml:equalityMatch>" + 527 " </dsml:not>" + 528 " <dsml:equalityMatch name=\"cn\">" + 529 " <dsml:value>g</dsml:value>" + 530 " </dsml:equalityMatch>" + 531 " <dsml:substrings name=\"cn\">" + 532 " <dsml:any>a</dsml:any>" + 533 " <dsml:any>b</dsml:any>" + 534 " <dsml:any>c</dsml:any>" + 535 " </dsml:substrings>" + 536 " <dsml:not>" + 537 " <dsml:substrings name=\"sn\">" + 538 " <dsml:final>h</dsml:final>" + 539 " </dsml:substrings>" + 540 " </dsml:not>" + 541 " </dsml:or>" + 542 " </dsml:or>" + 543 " </dsml:not>" + 544 " </dsml:filter>"; 545 546 549 private static String deleteRequest1 = 550 " <dsml:delRequest dn=\"cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU\"/>"; 551 552 557 public void testDeleteRequest() 558 throws NamingException 559 { 560 StringBuffer buffy = new StringBuffer (); 561 DsmlContext.getDeleteRequestElement(buffy, "cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU"); 562 assertXMLEquals(deleteRequest1, buffy.toString()); 563 } 564 565 private static String escapeString = "<>&'"fred"; 566 private static String rawString = "<>&'\"fred"; 567 private static String yuckyEscapeString = "<>&'"BHA@"; 568 569 public void testEscape() 570 { 571 assertEquals(escapeString, DsmlContext.escape(rawString)); 572 } 573 574 public void testUnescape() 575 { 576 assertEquals(rawString, DsmlContext.unescape(escapeString)); 577 assertEquals(rawString, DsmlContext.unescape(yuckyEscapeString)); 578 } 579 580 private static String stringElement = "<dsml:value>organizationalPerson</dsml:value>"; 581 private static String binaryElement = "<dsml:value xsi:type=\"xsd:base64Binary\">c2VjcmV0IHBhc3N3b3Jk</dsml:value>"; 582 private static byte[] password = new byte[]{115, 101, 99, 114, 101, 116, 32, 112, 97, 115, 115, 119, 111, 114, 100}; private static String address = "21 Jump Street$New York$90210"; 584 585 public void testCreateDsmlElement() 586 throws NamingException 587 { 588 StringBuffer buffy1 = new StringBuffer (); 589 DsmlContext.createDsmlValueElement("organizationalPerson", buffy1); 590 assertEquals(stringElement, buffy1.toString().trim()); 591 592 StringBuffer buffy2 = new StringBuffer (); 593 DsmlContext.createDsmlValueElement(password, buffy2); 594 assertEquals(binaryElement, buffy2.toString().trim()); 595 } 596 597 600 private static String addRequest1 = 601 " <dsml:addRequest dn=\"cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU\">" + 602 " <dsml:attr name=\"cn\">" + 603 " <dsml:value>Alana SHORE</dsml:value>" + 604 " </dsml:attr>" + 605 " <dsml:attr name=\"objectClass\">" + 606 " <dsml:value>inetOrgPerson</dsml:value>" + 607 " <dsml:value>organizationalPerson</dsml:value>" + 608 " <dsml:value>person</dsml:value>" + 609 " <dsml:value>top</dsml:value>" + 610 " </dsml:attr>" + 611 " <dsml:attr name=\"sn\">" + 612 " <dsml:value>SHORE</dsml:value>" + 613 " </dsml:attr>" + 614 " <dsml:attr name=\"userPassword\">" + 615 " <dsml:value xsi:type=\"xsd:base64Binary\">c2VjcmV0IHBhc3N3b3Jk</dsml:value>" + 616 " </dsml:attr>" + 617 " </dsml:addRequest>"; 618 619 620 public void testAddRequest() 621 throws NamingException 622 { 623 OrderedAttributes testAtts = new OrderedAttributes(); 624 testAtts.put(new BasicAttribute("cn", "Alana SHORE")); 625 OrderedAttribute oc = new OrderedAttribute("objectClass"); 626 oc.add("inetOrgPerson"); 627 oc.add("organizationalPerson"); 628 oc.add("person"); 629 oc.add("top"); 630 testAtts.put(oc); 631 testAtts.put(new BasicAttribute("userPassword", password)); 632 testAtts.put(new BasicAttribute("sn", "SHORE")); 633 634 String dn = "cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU"; 635 636 StringBuffer addRequest = new StringBuffer (); 637 DsmlContext.getAddRequestElement(addRequest, dn, testAtts); 638 639 641 assertXMLEquals(addRequest1, addRequest.toString()); 642 } 643 644 645 648 private static String modifyRequest1 = 649 "<dsml:batchRequest xmlns:dsml=\"urn:oasis:names:tc:DSML:2:0:core\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + 650 " <dsml:modifyRequest dn=\"cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU\">" + 651 " <dsml:modification name=\"favoriteDrink\" operation=\"add\">" + 652 " <dsml:value>japanese slipper</dsml:value>" + 653 " </dsml:modification>" + 654 " <dsml:modification name=\"sn\" operation=\"delete\"/>" + 655 " <dsml:modification name=\"userPassword\" operation=\"replace\">" + 656 " <dsml:value xsi:type=\"xsd:base64Binary\">c2VjcmV0IHBhc3N3b3Jk</dsml:value>" + 657 " </dsml:modification>" + 658 " </dsml:modifyRequest>" + 659 "</dsml:batchRequest>"; 660 661 664 private static String modifyRequest2 = 665 "<dsml:batchRequest xmlns:dsml=\"urn:oasis:names:tc:DSML:2:0:core\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + 666 " <dsml:modifyRequest dn=\"cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU\">" + 667 " <dsml:modification name=\"jpegPhoto\" operation=\"add\">" + 668 " <dsml:value xsi:type=\"xsd:base64Binary\">/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAA3ACkDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD7KqK5mitreS4nkWOKJC8jscBVAySamxzXk37WviZ/DHwK16aGXy7m/RbCAjs0p2n/AMd3VpSh7Saj3E3ZXMT4a/tLeB/F/inU9DuXbSfJnIsbi4b93dRjjJPRGyOh7V7XaXtndrutbqGcYz+7cN/KvgbwTonijT/BFrquh+EZtW0N5/ssrW1uskrSfxORjOPfpXq3wG0fxHZfGiXXbJli8NRacYL1Gl2FXOCqeX3II69smvpcwybC0aU5xqe/HeKTaTeyv09ddexwUsVUlUUXHR7M+q6MUKQwDDoaWvlj0AyPWvlL/gojrhi8LeG/DscgDXV61zIuOdsa4H6tX0F431W90WeC+s1EoEbCSFj8rge/Y18a/tXeONY8fXemSz6XaadpGizncPN3ztI2AWP+yMdB7mpy7H0J4t0W7STtr5rf8QrUpRpqXc1fgF8cp/Bvw/Tw/cabLclGdrSWMgAM3VXB9D3rpfg/qBuvFmnajqt5IiT3pa7EbYV95JUEf3Q+2vnrSJ4XvLwQMHiWRfmXpkjnFdfpHiS4sIjFZlDMFJUyvtTI5AJ/Kv1yhgaE6NS1r1FZvva6v+uh87Vqz5o26H6IDGOMUlcx8KZNcm+HWhTeJJ45tWls0kuHQcEtyPrwQM966j86/KKsPZ1JQvezsfQRd0mZXiXT1v8ATyhAJXJ59O9eDeI/2d9O8eS3OpS6xc6dAwLWiQoCssg6SOD1T/ZGM+tfRzKCCCMg01VWOMKihVUYAHQV5tLBRpY/67B2lZadLrqbSqOVP2b2PzR1rRL3wzqF3pWoWf2S6trhoJU243MP4sehHINQWyCaAWzgss8iocDJClhux+Ga+h/Ffwe8R/ETRNa8VW999o8QJq9wlukxCRXUCMVAH91hjAPTiuo/Zu+BN34YvD4m8bRW0mpBDHaWIIkS3B+87HoznGBjgDPrX6v/AKxYNYVVYNXstFpq0nt0VzwvqdR1LdD2D4d6pY6xoFld6Q92bCK3S3U3EJQuVUAMM/zrp9vuaSNFjQIihUAwFAwBT6/Nmk22la57KukFQ3YkNvIsLBZGXCn0J6GiiiSugItIsLfS9Nt9PtQRDAgRc9T6k+5PNW6KKIpJWQBRRRTA/9k=</dsml:value>" + 669 " </dsml:modification>" + 670 " </dsml:modifyRequest>" + 671 "</dsml:batchRequest>"; 672 673 private static String modifyRequest3 = 674 " <dsml:modifyRequest dn=\"cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU\">\n" + 675 " <dsml:modification name=\"userPassword\" operation=\"add\">\n" + 676 " <dsml:value xsi:type=\"xsd:base64Binary\">c2VjcmV0IHBhc3N3b3Jk</dsml:value>\n" + 677 " </dsml:modification>\n" + 678 " <dsml:modification name=\"address\" operation=\"delete\">\n" + 679 " <dsml:value>21 Jump Street$New York$90210</dsml:value>\n" + 680 " </dsml:modification>\n" + 681 " <dsml:modification name=\"objectClass\" operation=\"replace\">\n" + 682 " <dsml:value>inetOrgPerson</dsml:value>\n" + 683 " <dsml:value>organizationalPerson</dsml:value>\n" + 684 " <dsml:value>person</dsml:value>\n" + 685 " <dsml:value>top</dsml:value>\n" + 686 " </dsml:modification>\n" + 687 " </dsml:modifyRequest>"; 688 689 public void testModRequest() 690 throws NamingException 691 { 692 OrderedAttributes testAtts = new OrderedAttributes(); 693 testAtts.put(new BasicAttribute("cn", "Alana SHORE")); 694 OrderedAttribute oc = new OrderedAttribute("objectClass"); 695 oc.add("inetOrgPerson"); 696 oc.add("organizationalPerson"); 697 oc.add("person"); 698 oc.add("top"); 699 700 String dn = "cn=Alana SHORE,ou=Infrastructure,ou=Support,o=DEMOCORP,c=AU"; 701 702 StringBuffer modRequest = new StringBuffer (); 703 704 ModificationItem[] mods = new ModificationItem[3]; 705 mods[0] = new ModificationItem(DsmlContext.ADD_ATTRIBUTE, new BasicAttribute("userPassword", password)); 706 mods[1] = new ModificationItem(DsmlContext.REMOVE_ATTRIBUTE, new BasicAttribute("address", address)); 707 mods[2] = new ModificationItem(DsmlContext.REPLACE_ATTRIBUTE, oc); 708 709 DsmlContext.getModRequestElement(modRequest, dn, mods); 710 712 assertXMLEquals(modifyRequest3, modRequest.toString()); 713 } 714 715 private static String escapedName1 = "cn=Juliet "<&>' LEVY"; 716 private static String unescapedName1= "cn=Juliet \"<&>' LEVY"; 717 718 public void testNameEscaping() 719 { 720 assertEquals(escapedName1, DsmlContext.escapeName(unescapedName1)); 721 } 722 723 private static String modDNRequest = 724 " <dsml:modDNRequest dn=\"CN=Alice Johnson,DC=Example,DC=COM\"\n" + 725 " newrdn=\"CN=Alice Weiss\"\n" + 726 " deleteoldrdn=\"false\"/>"; 727 728 private static String modDNRequest2 = 729 " <dsml:modDNRequest dn=\"CN=Alice Johnson,DC=Example,DC=COM\"\n" + 730 " newrdn=\"CN=Alice Weiss\"\n" + 731 " deleteoldrdn=\"true\"/>"; 732 733 private static String modDNRequest3 = 734 " <dsml:modDNRequest dn=\"CN=Alice Johnson,DC=Example,DC=COM\"\n" + 735 " newrdn=\"CN=Alice Weiss\"\n" + 736 " deleteoldrdn=\"true\"/>"; 737 738 745 750 private static String modDNRequest4 = 751 " <dsml:modDNRequest dn=\"CN=Alice Johnson,DC=Example,DC=COM\"\n" + 752 " newrdn=\"CN=Alice Weiss\"\n" + 753 " deleteoldrdn=\"true\"/>"; 754 755 756 757 public void testModDNRequest() 758 throws NamingException 759 { 760 Hashtable env = new Hashtable(); 761 env.put("java.naming.ldap.deleteRDN", "false"); 762 DsmlContext testCtx = new DsmlContext(env); 763 764 StringBuffer buffy = new StringBuffer (); 765 testCtx.getModDNRequestElement(buffy, "CN=Alice Johnson,DC=Example,DC=COM", "CN=Alice Weiss"); 766 assertXMLEquals(modDNRequest, buffy.toString()); 767 768 testCtx.addToEnvironment("java.naming.ldap.deleteRDN", "true"); 769 buffy = new StringBuffer (); 770 testCtx.getModDNRequestElement(buffy, "CN=Alice Johnson,DC=Example,DC=COM", "CN=Alice Weiss"); 771 assertXMLEquals(modDNRequest2, buffy.toString()); 772 773 testCtx.addToEnvironment("java.naming.ldap.deleteRDN", "true"); 774 buffy = new StringBuffer (); 775 testCtx.getModDNRequestElement(buffy, "CN=Alice Johnson,DC=Example,DC=COM", "CN=Alice Weiss"); 776 assertXMLEquals(modDNRequest3, buffy.toString()); 777 778 testCtx.addToEnvironment("java.naming.ldap.deleteRDN", "true"); 779 buffy = new StringBuffer (); 780 testCtx.getModDNRequestElement(buffy, "CN=Alice Johnson,DC=Example,DC=COM", "CN=Alice Weiss"); 781 assertXMLEquals(modDNRequest4, buffy.toString()); 782 783 } 784 785 788 private static String searchRequest4 = 789 "<dsml:batchRequest xmlns:dsml=\"urn:oasis:names:tc:DSML:2:0:core\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" + 790 " <dsml:searchRequest dn=\"c=AU\" scope=\"wholeSubtree\" derefAliases=\"derefInSearching\">" + 791 " <dsml:filter>" + 792 " <dsml:equalityMatch name=\"cn\">" + 793 " <dsml:value>Alana SHORE</dsml:value>" + 794 " </dsml:equalityMatch>" + 795 " </dsml:filter>" + 796 " <dsml:attributes>" + 797 " <dsml:attribute name=\"objectClass\"/>" + 798 " </dsml:attributes>" + 799 " </dsml:searchRequest>" + 800 "</dsml:batchRequest>"; 801 802 805 private static String addResponse = 806 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + 807 "<batchResponse xmlns=\"urn:oasis:names:tc:DSML:2:0:core\">" + 808 "<addResponse>" + 809 "<resultCode code=\"0\"/>" + 810 "</addResponse>" + 811 "</batchResponse>\n\n"; 812 813 816 private static String delResponse = 817 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + 818 "<batchResponse xmlns=\"urn:oasis:names:tc:DSML:2:0:core\">" + 819 "<delResponse>" + 820 "<resultCode code=\"0\"/>" + 821 "</delResponse>" + 822 "</batchResponse>\n\n"; 823 824 private static String delResponse2 = 826 "<delResponse matchedDN=\"OU=HR,DC=Example,DC=COM\">\n" + 827 " <resultCode code=\"32\" descr=\"noSuchObject\"/>\n" + 828 " <errorMessage>DSDEL::230234</errorMessage>\n" + 829 "</delResponse>\n"; 830 831 private static String modResponse2 = 833 "<modifyResponse>\n" + 834 " <resultCode code=\"53\" descr=\"unwillingToPerform\"/>\n" + 835 " <errorMessage>System Attribute may not be modified</errorMessage>\n" + 836 "</modifyResponse>\n"; 837 838 private static String errorResponse = 839 " <errorResponse type=\"malformedRequest\">\n" + 840 " <message>Unknown element ‘bogusRequest’ line 87 column 4</message>\n" + 841 " </errorResponse>"; 842 843 public void testErrorResponse() 845 { 846 try 847 { 848 DsmlContext.checkForError(delResponse2); 849 fail("no exception thrown when parsing error responses"); 850 } 851 catch (NamingException e) 852 { 853 assertEquals(e.getMessage(), "noSuchObject Exception (LDAP 32)\nDSDEL::230234"); 856 } 857 858 try 859 { 860 DsmlContext.checkForError(modResponse2); 861 fail("no exception thrown when parsing error responses"); 862 } 863 catch (NamingException e) 864 { 865 assertEquals(e.getMessage(), "unwillingToPerform Exception (LDAP 53)\nSystem Attribute may not be modified"); 868 } 869 870 try 871 { 872 DsmlContext.checkForError(errorResponse); 873 fail("no exception thrown when parsing error responses"); 874 } 875 catch (NamingException e) 876 { 877 assertEquals(e.getMessage(), "Error Processing DSML Request: malformedRequest\nUnknown element ‘bogusRequest’ line 87 column 4"); 880 } 881 } 882 883 886 private static String modifyResponse = 887 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + 888 "<batchResponse xmlns=\"urn:oasis:names:tc:DSML:2:0:core\">" + 889 "<modifyResponse>" + 890 "<resultCode code=\"0\"/>" + 891 "</modifyResponse>" + 892 "</batchResponse>\n\n"; 893 894 897 private static String modifyDNResponse = 898 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + 899 "<batchResponse xmlns=\"urn:oasis:names:tc:DSML:2:0:core\">" + 900 "<modDNResponse>" + 901 "<resultCode code=\"0\"/>" + 902 "</modDNResponse>" + 903 "</batchResponse>\n\n"; 904 905 913 914 915 922 public static void assertXMLEquals(String xml1, String xml2) 923 { 924 StringTokenizer firstString = new StringTokenizer(xml1, " \r\n\t\f"); 925 StringTokenizer secondString = new StringTokenizer(xml2, " \r\n\t\f"); 926 927 StringBuffer firstXML = new StringBuffer (xml1.length()); 928 StringBuffer secondXML = new StringBuffer (xml2.length()); 929 930 while (firstString.hasMoreTokens()) 931 { 932 firstXML.append(firstString.nextToken()); 933 } 934 935 while (secondString.hasMoreTokens()) 936 { 937 secondXML.append(secondString.nextToken()); 938 } 939 assertEquals(firstXML.toString(), secondXML.toString()); 940 } 941 942 945 class OrderedAttributes extends BasicAttributes 946 { 947 public OrderedAttributes() 948 { 949 super(); 950 } 951 952 public OrderedAttributes(String id, Object val) 953 { 954 super(id, val); 955 } 956 957 962 963 public OrderedAttributes(Attributes atts) 964 { 965 Enumeration en = atts.getAll(); 966 while (en.hasMoreElements()) 967 { 968 this.put((Attribute) en.nextElement()); 969 } 970 } 971 972 public NamingEnumeration getAll() 973 { 974 DXNamingEnumeration sortedByID = new DXNamingEnumeration(); 975 NamingEnumeration IDs = getIDs(); 976 while (IDs.hasMoreElements()) 977 { 978 Attribute att = this.get((String ) IDs.nextElement()); 979 sortedByID.add(att); 980 } 981 return sortedByID; 982 } 983 984 public NamingEnumeration getIDs() 985 { 986 Enumeration original = super.getIDs(); 987 DXNamingEnumeration sortedEnum = new DXNamingEnumeration(original); 988 sortedEnum.sort(); 989 return sortedEnum; 990 991 } 992 } 993 994 997 998 class OrderedAttribute extends BasicAttribute 999 { 1000 public OrderedAttribute(String id) 1001 { 1002 super(id); 1003 } 1004 1005 public NamingEnumeration getAll() 1006 throws NamingException 1007 { 1008 DXNamingEnumeration sortedByID = new DXNamingEnumeration(); 1009 1010 for (int i = 0; i < size(); i++) 1011 { 1012 Object val = this.get(i); 1013 sortedByID.add(val); 1014 } 1015 return sortedByID; 1016 } 1017 1018 } 1019 1020 public void testSchemaResultParse() 1021 throws Exception 1022 { 1023 StringBuffer bigSchema = new StringBuffer (400000); 1024 BufferedReader br = null; 1025 try 1026 { 1027 br = new BufferedReader(new FileReader("DsmlContextTestData.txt")); 1028 for (String s = br.readLine(); s != null; s = br.readLine()) 1029 { 1030 bigSchema.append(s); 1031 } 1032 } 1033 catch (FileNotFoundException e) 1034 { 1035 System.out.println("SKIPPING testSchemaResultParse - can't find DsmlContextTestData.txt"); 1036 return; 1037 } 1038 finally 1039 { 1040 if (br != null) br.close(); 1041 } 1042 1043 1044 DXNamingEnumeration results1 = new DXNamingEnumeration(DsmlContext.parseSearchResponse(bigSchema.toString(), "")); 1045 1046 assertEquals(results1.size(), 1); 1047 1048 SearchResult result = (SearchResult) results1.next(); 1049 1050 String dn = result.getName(); 1051 1052 assertEquals(dn, "cn=schema"); 1053 1054 OrderedAttributes atts = new OrderedAttributes(result.getAttributes()); 1055 1056 DXNamingEnumeration attEnum = new DXNamingEnumeration(atts.getAll()); 1057 1058 attEnum.sort(); 1059 1060 assertEquals(attEnum.size(), 7); 1061 1062 Object [] attributeArray = attEnum.toArray(); 1063 1064 assertEquals(((Attribute)attributeArray[0]).getID(), "attributeTypes"); 1065 1066 assertEquals(((Attribute)attributeArray[6]).getID(), "objectClasses"); 1067 1068 DXNamingEnumeration objectClassesValues = new DXNamingEnumeration(((Attribute)attributeArray[6]).getAll()); 1069 1070 objectClassesValues.sort(); 1071 1072 String [] values = objectClassesValues.toStringArray(); 1073 1074 int len = values.length; 1075 1076 assertEquals(263, len); 1077 1078 assertEquals("( 0.9.2342.19200300.100.4.13 NAME 'domain' SUP ( top ) STRUCTURAL MUST ( dc ) MAY ( associatedName $ o $ description $ l $ st $ street $ physicalDeliveryOfficeName $ postalAddress $ postalCode $ postOfficeBox $ street $ facsimileTelephoneNumber $ internationaliSDNNumber $ telephoneNumber $ teletexTerminalIdentifier $ telexNumber $ preferredDeliveryMethod $ destinationIndicator $ registeredAddress $ x121Address $ businessCategory $ seeAlso $ searchGuide $ userPassword ) )", values[0]); 1080 1081 assertEquals("( 2.6.5.1.4 NAME 'mhsUserAgent' SUP ( applicationEntity ) STRUCTURAL MAY ( mhsDeliverableContentLength $ mhsDeliverableContentTypes $ mhsDeliverableEits $ mhs-or-addresses $ owner ) )", values[len-1]); 1083 } 1084 1085} | Popular Tags |