1 package com.ca.commons.naming; 2 3 4 import com.ca.commons.cbutil.*; 5 import com.ca.commons.jndi.AdvancedOps; 6 import com.ca.commons.jndi.ConnectionData; 7 8 import javax.naming.*; 9 import javax.naming.directory.*; 10 import java.io.UnsupportedEncodingException ; 11 import java.net.URLDecoder ; 12 import java.util.logging.Level ; 13 import java.util.logging.Logger ; 14 15 19 20 public class DXOps extends AdvancedOps 21 { 22 23 private final static Logger log = Logger.getLogger(DXOps.class.getName()); 24 25 28 29 30 public DXOps(DirContext ctx) 31 throws NamingException 32 { 33 super(ctx); 34 } 35 36 public DXOps(ConnectionData cData) 37 throws NamingException 38 { 39 super(cData); 40 } 41 42 43 50 51 public Name preParse(Name name) 52 { 53 return name; 56 } 57 58 65 66 public Name postParse(Name name) 67 { 68 return postParse(name.toString()); 69 } 70 71 80 86 public Name postParse(String name) 87 { 88 93 if (name.charAt(name.length() - 1) == '\\') 94 { 95 name = NameUtility.checkEndSpaces(name); 96 } 97 98 99 try 100 { 101 Name cn = new CompositeName(name); 102 if (cn.size() == 0) return new DN(); 105 return new DN(cn.get(cn.size() - 1)); } 107 catch (NamingException e) { 109 log.log(Level.WARNING, "unexpected error: bad name back from jndi ftn in CBOps.postParse(" + name + ")?", e); 110 e.printStackTrace(); 111 return new DN(name); } 114 } 115 116 125 public String postParseString(String name) 126 { 127 132 133 if (name.length() == 0) 134 return name; 135 136 if (name.charAt(name.length() - 1) == '\\') 137 { 138 name = NameUtility.checkEndSpaces(name); 139 } 140 if (name.startsWith("ldap://")) 141 { 142 try 143 { 144 name = URLDecoder.decode(name, "UTF8"); 145 } 146 catch (UnsupportedEncodingException e) 147 { 148 log.severe("unexpected error: couldn't URL decode in CBOps.postParseString(" + name + ")?\n" + e.toString()); 149 e.printStackTrace(); 150 return name; 151 } 152 } 153 154 157 158 try 159 { 160 Name cn = new CompositeName(name); if (cn.size() == 0) return ""; 164 name = cn.get(cn.size() - 1); 165 168 return name; } 170 catch (NamingException e) { 172 log.log(Level.WARNING, "unexpected error: bad name back from jndi ftn in CBOps.postParseString(" + name + ")?", e); 173 e.printStackTrace(); 174 return name; } 176 177 } 178 179 180 192 public NamingEnumeration postParseNameClassPairs(NamingEnumeration names, Name base) 193 { 194 log.finer("parsing with base :" + base.toString()); 195 DXNamingEnumeration dxe = new DXNamingEnumeration(); 196 197 String baseString = null; 198 199 if (base != null && base.isEmpty() == false) 200 baseString = base.toString(); 201 202 try 203 { 204 while (names.hasMore()) 205 { 206 NameClassPair ncp = (NameClassPair) names.next(); 207 208 String rawName = postParseString(ncp.getName()).toString(); 209 210 213 if (ncp.isRelative() && baseString != null) 214 { 215 if (rawName.length() != 0) 216 rawName = rawName + "," + baseString; 217 else 218 rawName = baseString; 219 } 220 221 log.finer("ended up with: '" + rawName + "'"); 222 ncp.setName(rawName); 223 dxe.add(ncp); 224 } 225 } 226 catch (NamingException ex) 227 { 228 CBUtility.error(CBIntText.get("Search partially failed! - only {0} entries returned", new Integer []{new Integer (dxe.size())}), ex); 229 } 230 231 return dxe; 232 } 233 234 235 278 279 291 protected NamingEnumeration rawSearchBaseEntry(Name searchbase, String filter, int limit, 292 int timeout, String [] returnAttributes) 293 throws NamingException 294 { 295 return postParseNameClassPairs(super.rawSearchBaseEntry(searchbase, filter, limit, timeout, returnAttributes), searchbase); 296 } 297 298 310 protected NamingEnumeration rawSearchOneLevel(Name searchbase, String filter, int limit, 311 int timeout, String [] returnAttributes) throws NamingException 312 { 313 return postParseNameClassPairs(super.rawSearchOneLevel(searchbase, filter, limit, timeout, returnAttributes), searchbase); 314 } 315 316 328 protected NamingEnumeration rawSearchSubTree(Name searchbase, String filter, int limit, 329 int timeout, String [] returnAttributes) throws NamingException 330 { 331 return postParseNameClassPairs(super.rawSearchSubTree(searchbase, filter, limit, timeout, returnAttributes), searchbase); 332 } 333 334 340 341 public void modifyEntry(DXEntry oldEntry, DXEntry newEntry) 342 throws NamingException 343 { 344 if (oldEntry != null) oldEntry.removeEmptyAttributes(); 345 if (newEntry != null) newEntry.removeEmptyAttributes(); 346 347 if (oldEntry == null && newEntry == null) { 349 } 350 else if (oldEntry == null || (newEntry != null) && (newEntry.getStatus() == DXEntry.NEW)) { 352 addEntryToDirectory(newEntry); 353 } 354 else if (newEntry == null) { 356 deleteTree(oldEntry.getDN()); 357 } 358 else if (oldEntry.getDN() == null || newEntry.getDN() == null) 359 { 360 throw new NamingException("Internal Error: Entry with null DN passed to JNDIBroker unthreadedModify. Modify Request Cancelled."); 361 } 362 else 363 { 364 handleAnyNameChange(oldEntry, newEntry); 366 367 updateEntry(oldEntry, newEntry); 369 } 370 } 371 372 377 378 private void addEntryToDirectory(DXEntry newEntry) 379 throws NamingException 380 { 381 addEntry(newEntry); 382 383 newEntry.setStatus(DXEntry.NEW_WRITTEN); } 385 386 391 392 public void addEntry(DXEntry newEntry) 393 throws NamingException 394 { 395 if (newEntry == null) 396 throw new NamingException("Internal Error: null Entry passed to DXOps addEntry"); 397 398 if (newEntry.getDN() == null) 399 throw new NamingException("Internal Error: Entry with null DN passed to DXOps addEntry"); 400 401 addEntry(newEntry.getDN(), newEntry); 402 } 403 404 405 412 413 private void handleAnyNameChange(DXEntry oldEntry, DXEntry newEntry) 414 throws NamingException 415 { 416 RDN oldRDN = oldEntry.getRDN(); 418 RDN newRDN = newEntry.getRDN(); 419 420 DN oldDN = oldEntry.getDN(); 421 DN newDN = newEntry.getDN(); 422 423 425 if (oldDN.equals(newDN)) 426 return; 428 if (oldEntry.size() == 0 && newEntry.size() == 0) { 430 moveTree(oldDN, newDN); 431 } 432 else if (oldRDN.isMultiValued() == false && newRDN.isMultiValued() == false) 433 { 434 renameSingleValuedRDNS(oldEntry, newEntry); 436 } 437 else 438 { 439 renameComplexMultiValuedRDNs(oldEntry, newEntry); 440 } 441 } 442 443 448 private void renameComplexMultiValuedRDNs(DXEntry oldEntry, DXEntry newEntry) 449 throws NamingException 450 { 451 String [] oldRDNs = oldEntry.getRDN().getElements(); 452 String [] newRDNs = newEntry.getRDN().getElements(); 453 454 DN oldDN = oldEntry.getDN(); 455 DN newDN = newEntry.getDN(); 456 457 460 461 Object [] temp = CBArray.difference(oldRDNs, newRDNs); 462 String [] lostRDNs = new String [temp.length]; 463 for (int i = 0; i < temp.length; i++) 464 lostRDNs[i] = temp[i].toString(); 465 466 467 468 476 final int NOT_SET = 0; 477 final int IN_NEW_ENTRY = 1; 478 final int NOT_IN_NEW_ENTRY = -1; 479 480 int deleteRDNState = NOT_SET; 481 482 for (int i = 0; i < lostRDNs.length; i++) 483 { 484 String RDN = lostRDNs[i]; String type = RDN.substring(0, RDN.indexOf('=')); 486 String value = RDN.substring(RDN.indexOf('=') + 1); 487 488 if (newEntry.get(type).contains(value) == true) 489 { 490 if (deleteRDNState == NOT_SET) deleteRDNState = IN_NEW_ENTRY; 492 if (deleteRDNState != IN_NEW_ENTRY) 493 { 494 setWierdoRDNError(oldDN, newDN); 495 } 496 } 497 else 498 { 499 if (deleteRDNState == NOT_SET) deleteRDNState = NOT_IN_NEW_ENTRY; 501 502 503 if (deleteRDNState != NOT_IN_NEW_ENTRY) 504 { 505 setWierdoRDNError(oldDN, newDN); 506 } 507 } 508 } 509 510 514 515 if (deleteRDNState == NOT_SET || deleteRDNState == IN_NEW_ENTRY) 516 { 517 renameEntry(oldDN, newDN, false); 518 } 519 else 520 { 521 renameEntry(oldDN, newDN, true); 522 for (int i = 0; i < lostRDNs.length; i++) 523 { 524 String RDN = lostRDNs[i]; String type = RDN.substring(0, RDN.indexOf('=')); 526 String value = RDN.substring(RDN.indexOf('=') + 1); 527 oldEntry.get(type).remove(value); } 529 } 530 } 531 532 533 private void renameSingleValuedRDNS(DXEntry oldEntry, DXEntry newEntry) 534 throws NamingException 535 { 536 RDN oldRDN = oldEntry.getRDN(); 537 538 String type = oldRDN.getAtt(); 539 String value = oldRDN.getRawVal(); 540 541 Attribute oldNamingAttInNewEntry = newEntry.get(type); 542 if (!oldNamingAttInNewEntry.contains(value)) 544 { 545 renameEntry(oldEntry.getDN(), newEntry.getDN(), true); 546 oldEntry.get(type).remove(value); } 548 else 550 { 551 renameEntry(oldEntry.getDN(), newEntry.getDN(), false); 552 } 553 } 554 555 556 566 567 private void setWierdoRDNError(DN oldDN, DN newDN) 568 throws NamingException 569 { 570 throw new NamingException(CBIntText.get("The rename operation is too complex to proceed. Try to break it up into smaller stages.") + 571 "\n " + oldDN.toString() + "\n => " + newDN.toString()); 572 } 573 574 575 576 579 580 593 594 601 602 public void updateEntry(DXEntry oldSet, DXEntry newSet) 603 throws NamingException 604 { 605 606 if (DXAttributes.attributesEqual(oldSet, newSet)) 607 return; 609 DN nodeDN = newSet.getDN(); 610 RDN newRDN = nodeDN.getLowestRDN(); 611 612 DXAttributes adds = null; DXAttributes reps = null; DXAttributes dels = null; 616 reps = DXAttributes.getReplacementSet(newRDN, oldSet, newSet); 617 dels = DXAttributes.getDeletionSet(newRDN, oldSet, newSet); 618 adds = DXAttributes.getAdditionSet(newRDN, oldSet, newSet); 619 620 if (false) 621 printDebug(oldSet, newSet, adds, reps, dels); 622 623 log.fine("updateNode: " + nodeDN); 624 625 ModificationItem[] mods; 626 627 mods = new ModificationItem[dels.size() + reps.size() + adds.size()]; 628 629 int modIndex = 0; 630 modIndex = loadMods(mods, dels.getAll(), DirContext.REMOVE_ATTRIBUTE, modIndex); 631 modIndex = loadMods(mods, adds.getAll(), DirContext.ADD_ATTRIBUTE, modIndex); 632 modIndex = loadMods(mods, reps.getAll(), DirContext.REPLACE_ATTRIBUTE, modIndex); 633 634 modifyAttributes(nodeDN, mods); } 636 637 638 649 650 private int loadMods(ModificationItem[] mods, NamingEnumeration atts, int TYPE, int index) 651 throws NamingException 652 { 653 while (atts.hasMore()) 654 { 655 Attribute temp = (Attribute) atts.next(); 656 mods[index++] = new ModificationItem(TYPE, temp); 657 } 658 return index; 659 } 660 661 662 671 672 private void printDebug(DXEntry oldSet, DXEntry newSet, DXAttributes adds, DXAttributes reps, DXAttributes dels) 673 { 674 675 676 System.out.println("\n*** entries are ***\n\nold:\n" + oldSet.toString() + "\n\nnew:\n" + newSet.toString()); 677 System.out.println("\n-----------------\nreps:\n" + reps.toString()); 678 System.out.println("\n-----------------\ndels:\n" + dels.toString()); 679 System.out.println("\n-----------------\nadds:\n" + adds.toString()); 680 } 682 } | Popular Tags |