1 5 package SOFA.SOFAnode.TR.Impl; 6 7 import SOFA.SOFAnode.InOut.Bundle; 8 import SOFA.SOFAnode.Run.Deployment.DeploymentDescriptorImpl; 9 import SOFA.SOFAnode.TR.*; 10 import SOFA.SOFAnode.TR.Connector.CNTR2InOut; 11 import SOFA.Util.Tools; 12 13 import javax.xml.parsers.ParserConfigurationException; 14 import java.io.*; 15 import java.rmi.RemoteException; 16 import java.util.*; 17 18 import org.xml.sax.SAXException; 19 20 25 public class TRImpl implements CNTR2InOut, TR2InOut { 26 27 30 private String dir; 31 32 35 private class ComponentStore { 36 37 41 private Hashtable componentInfos; 42 43 48 private Hashtable componentFiles; 49 50 53 private ComponentStore () { 54 componentInfos = new Hashtable(); 55 componentFiles = new Hashtable(); 56 } 57 58 63 private void addFiles (ComponentInfo info, ComponentFiles files) { 64 componentInfos.put(info, info); 65 componentFiles.put(info, files); 66 } 67 68 73 private ComponentFiles getFiles (ComponentInfo info) { 74 return (ComponentFiles) componentFiles.get(info); 75 } 76 77 78 83 84 private ComponentFiles removeFiles (ComponentInfo info) { 85 return (ComponentFiles) componentFiles.remove(info); 86 } 87 88 93 private ComponentInfoImpl getInfo (ComponentInfo info) { 94 return (ComponentInfoImpl) componentInfos.get(info); 95 } 96 97 102 private ComponentInfoImpl removeInfo (ComponentInfo info) { 103 return (ComponentInfoImpl) componentInfos.remove(info); 104 } 105 106 111 private ComponentInfoImpl getInfo (String fullName) { 112 return getInfo(ComponentInfoImpl.fromString(fullName)); 113 } 114 115 119 private Set getInfos () { 120 return componentInfos.keySet(); 121 } 122 123 128 private boolean contains (ComponentInfo info) { 129 return componentInfos.contains(info); 130 } 131 132 141 void setSubComponents (ComponentInfoImpl info) throws IOException, ParserConfigurationException, SAXException { 142 ComponentFiles files = (ComponentFiles) componentFiles.get(info); 143 if (files == null) return; 145 AssemblyDescriptorImpl ad = new AssemblyDescriptorImpl(files.getAssemblyDescriptorFile()); 146 Set set = ad.getSubComponents(); Set subComponents = new HashSet(); for (Iterator iterator = set.iterator(); iterator.hasNext();) { 149 String fullName = (String) iterator.next(); 150 iterator.remove(); 151 ComponentInfo comp = ComponentInfoImpl.fromString(fullName); 152 subComponents.add(comp); 153 } 154 155 info.setSubComponents((ComponentInfoImpl[]) subComponents.toArray(new ComponentInfoImpl[subComponents.size()])); 156 157 161 162 } 163 } 164 165 168 private ComponentStore components; 169 170 173 private Properties implIndex; 174 175 178 private Properties ifaceIndex; 179 180 183 private String implPath; 184 185 188 private String ifacePath; 189 190 195 public TRImpl (String dir) throws RemoteException, TRException { 196 this.dir = dir; 197 init(); 198 } 199 200 204 private synchronized void init () throws TRException { 205 components = new ComponentStore(); 208 209 implIndex = new Properties(); 211 ifaceIndex = new Properties(); 212 implPath = dir + File.separator + "impl" + File.separator; 213 ifacePath = dir + File.separator + "iface" + File.separator; 214 try { 215 FileInputStream fis = new FileInputStream(implPath + "info"); 216 implIndex.load(fis); 217 fis.close(); 218 219 fis = new FileInputStream(ifacePath + "index"); 220 ifaceIndex.load(fis); 221 fis.close(); 222 223 } catch (java.io.IOException e) { 224 System.out.println("IOException: " + e.getMessage()); 225 System.exit(1); 226 } 227 228 Set collection = implIndex.keySet(); 231 for (Iterator iterator = collection.iterator(); iterator.hasNext();) { 233 String nameVer = (String) iterator.next(); 236 String name = nameVer.substring(0, nameVer.lastIndexOf('[')); String path = fullNameToFileName(nameVer); 239 240 AssemblyDescriptorImpl ad = null; 241 try { 242 ad = new AssemblyDescriptorImpl(new File(dir + File.separator + "impl" + path + "index.dc")); 243 } catch (Exception e) { 244 throw new TRException("Exception thrown when initializing TR!\n" + 245 "When creating the assembly descriptor!\n" + path + "\n" + e, e); 246 } 247 ComponentInfo info = new ComponentInfoImpl(name, ad.getImplementationVersion()); 248 ComponentFiles files = new ComponentFiles(); 249 files.addFiles(dir + File.separator + "impl" + path, ""); 250 251 Map cdl = ad.getCDLEntities(); 252 for (Iterator javaNames = cdl.keySet().iterator(); javaNames.hasNext();) { 253 String key = (String) javaNames.next(); 254 String value = (String) cdl.get(key); 255 String ifaceDir = (String) ifaceIndex.get(value); 256 String connPath = key.replace('.', File.separatorChar); 257 String connName = File.separator + connPath + ".class"; 258 files.addFiles(ifacePath + ifaceDir + connName, connName); 259 } 260 components.addFiles(info, files); 261 } 264 265 collection = components.getInfos(); 268 for (Iterator iterator = collection.iterator(); iterator.hasNext();) { ComponentInfoImpl info = (ComponentInfoImpl) iterator.next(); 272 273 try { 274 components.setSubComponents(info); 275 } catch (Exception e) { 276 throw new TRException("Exception thrown when initializing TR!\n" + 277 "When setting subcomponents of the component:\n" + info + "\n" + e, e); 278 } 279 } 280 281 } 282 283 288 private static String fullNameToFileName (String clname) { 289 return clname.replaceAll("::|\\[|\\]", "\\" + File.separator); 290 308 } 309 310 318 public synchronized void storeBundle (Bundle bundle) throws TRException { 319 ComponentInfo[] compInfos = bundle.getComponents(); 320 321 System.out.println("TR: Storing a bundle containing following components:"); 323 for (int i = 0; i < compInfos.length; i++) { 324 ComponentInfoImpl info = (ComponentInfoImpl) compInfos[i]; 325 ComponentFiles files = (ComponentFiles) bundle.getComponent(info); 328 Hashtable filesTable = (files).getFiles(); 329 String location = info.getLocation(); 331 if (location.startsWith("sofa://")) { System.out.println("Description of: " + info.getName() + "[" + info.getImplementationVersion() + "]"); continue; 334 } 335 String name = info.getName(); 336 String version = info.getImplementationVersion(); 337 System.out.println("Full component: " + name + "[" + version + "]"); 339 File file = (File) filesTable.get("/" + "index.dc"); 340 String indexPath = file.getPath(); 341 342 DeploymentDescriptorImpl dd = null; 343 try { 344 dd = new DeploymentDescriptorImpl(indexPath); 345 } catch (Exception e) { 346 throw new TRException("Exception thrown when storing a bundle to TR!\n" + 347 "When creating the assembly descriptor of the component:\n" + info + "\n" + e, e); 348 } 349 350 Hashtable cdl = dd.getCDLEntities(); 351 352 Enumeration enum = filesTable.keys(); 353 while (enum.hasMoreElements()) { 354 String fileName = (String) enum.nextElement(); File srcFile = (File) filesTable.get(fileName); filesTable.remove(fileName); 357 fileName = fileName.replace('/', File.separatorChar); 358 if (fileName.endsWith(".class")) { 359 String key = fileName.substring(1, fileName.length() - ".class".length()).replace(File.separatorChar, '.'); 360 if (cdl.containsKey(key)) { 361 String fullName = (String) cdl.get(key); String ifaceDir; 363 try { 364 ifaceDir = getInterfaceDirectory(fullName); 365 } catch (IOException e) { 366 throw new TRException("Exception thrown when storing a bundle to TR!\n" + 367 "When learning a directory where to store the interface '" + fullName + "'!\n" + e, e); 368 } 369 File destFile = new File(dir + File.separator + "iface" + File.separator + ifaceDir + fileName); 370 ifaceIndex.put(fullName, ifaceDir); moveFile(srcFile, destFile); 372 filesTable.put(fileName, destFile); 373 continue; } 375 } 376 378 File destFile = new File(dir + File.separator + "impl" + fullNameToFileName(name + "[" + version) + fileName); 379 moveFile(srcFile, destFile); 380 381 filesTable.put(fileName, destFile); 382 } String fullName = name + "[" + version + "]"; 384 implIndex.put(fullName, "1"); info.setLocation(fullName); 386 components.addFiles(info, files); 387 } 389 System.out.println("End ------------------------------------------------------"); 391 for (int i = 0; i < compInfos.length; i++) { 393 ComponentInfoImpl info = (ComponentInfoImpl) compInfos[i]; 394 try { 395 components.setSubComponents(info); 396 } catch (Exception e) { 397 throw new TRException("Exception thrown when storing a bundle to TR!\n" + 398 "When setting subcomponents of the component:\n" + info + "\n" + e, e); 399 } 400 } 402 try { 404 saveProperties(); 405 } catch (IOException e) { 406 throw new TRException("Exception thrown when storing a bundle to TR!\n" + 407 "When saving properties!\n" + e); 408 } 409 } 410 411 427 private String getInterfaceDirectory (String fullName) throws IOException { 428 synchronized (ifaceIndex) { 429 String ifaceDir = (String) ifaceIndex.get(fullName); 430 if (ifaceDir != null) return ifaceDir; if (ifaceIndex.isEmpty()) return getLastIndex(); String name = fullName.substring(0, fullName.indexOf('?')); 435 HashSet temp = new HashSet(); 436 temp.addAll(ifaceIndex.values()); Iterator iter = ifaceIndex.keySet().iterator(); 438 while (iter.hasNext()) { String fullName2 = (String) iter.next(); 440 String name2 = fullName2.substring(0, fullName2.indexOf('?')); 441 if (name2.equals(name)) { String ifaceDir2 = (String) ifaceIndex.get(fullName2); 443 temp.remove(ifaceDir2); } 445 } 446 if (!temp.isEmpty()) return (String) temp.iterator().next(); ifaceDir = incrementLastIndex(getLastIndex()); storeLastIndex(ifaceDir); 450 File d = new File(dir + File.separator + "iface" + File.separator + ifaceDir); 451 d.mkdir(); 452 return ifaceDir; 453 } 454 } 455 456 463 private static String incrementLastIndex (String last) { 464 StringBuffer sb = new StringBuffer(last); 465 int now = last.length() - 1; 466 while (true) { 467 if (last.charAt(now) != 'z') { 468 sb.setCharAt(now, (char) (last.charAt(now) + (char) 1)); 469 return sb.toString(); 470 } 471 sb.setCharAt(now, 'a'); 472 now--; 473 if (now < 0) { 474 sb.append('a'); 475 return sb.toString(); 476 } 477 } 478 } 479 480 486 private String getLastIndex () throws IOException { 487 FileInputStream fis = new FileInputStream(dir + File.separator + "iface" + File.separator + "last"); 488 StringBuffer sb = new StringBuffer(); 489 int a = 0; 490 a = fis.read(); 491 while (a != -1) { 492 sb.append((char) a); 493 a = fis.read(); 494 } 495 fis.close(); 496 return sb.toString(); 497 } 498 499 504 private void storeLastIndex (String last) throws IOException { 505 FileOutputStream fos = new FileOutputStream(dir + File.separator + "iface" + File.separator + "last"); 506 for (int i = 0; i < last.length(); i++) { 507 fos.write((byte) last.charAt(i)); 508 } 509 fos.close(); 510 } 511 512 516 private void saveProperties () throws IOException { 517 FileOutputStream fos = new FileOutputStream(implPath + "info"); 518 implIndex.store(fos, null); 519 fos.close(); 520 521 fos = new FileOutputStream(ifacePath + "index"); 522 ifaceIndex.store(fos, null); 523 fos.close(); 524 } 525 526 533 private static void moveFile (File srcFile, File destFile) 534 { 535 try { 536 Tools.moveFile(srcFile, destFile); 537 } catch (IOException e) { 538 throw new TRException("Exception thrown when moving a component file!\n" + 539 "source file:" + srcFile.getName() + "\ndest file:" + destFile.getName(), e); 540 } 541 } 542 543 553 public synchronized Bundle getBundle (ComponentInfo[] descs, ComponentInfo[] comps, boolean inferiors) throws TRException { 554 if (inferiors) { 555 descs = getTransitiveClosure(descs); 556 comps = getTransitiveClosure(comps); 557 } 558 559 System.out.println("TR: Getting a bundle containing following components:"); 561 BundleImpl bundle = new BundleImpl(); 562 if (comps != null) { 563 for (int i = 0; i < comps.length; i++) { 564 ComponentInfo info = comps[i]; 565 System.out.println("Full component: " + info.getName() + "[" + info.getImplementationVersion() + "]"); ComponentFiles files = components.getFiles(info); 567 if (files == null) throw new TRException("Required component not stored in this TR!" + info); 568 bundle.add((ComponentInfoImpl) info, files); 569 } 570 } 571 if (descs != null) { 572 for (int i = 0; i < descs.length; i++) { 573 ComponentInfo info = descs[i]; 574 System.out.println("Description of: " + info.getName() + "[" + info.getImplementationVersion() + "]"); bundle.add((ComponentInfoImpl) info, BundleImpl.NO_FILES); 576 } 577 } 578 System.out.println("End ------------------------------------------------------"); return bundle; 580 } 581 582 590 public synchronized void deleteComponents (ComponentInfo[] comps, boolean interfaces, boolean inferiors) throws TRException 591 { 592 if (inferiors) 593 { 594 comps = getTransitiveClosure(comps); 595 } 596 String msg; 597 598 if (!interfaces) msg = "TR: Deleting components (without interfaces):"; 599 else msg = "TR: Deleting components (with interfaces):"; 600 601 System.out.println(msg); if (comps != null) 603 { 604 for (int i = 0; i < comps.length; i++) 605 { 606 ComponentInfo comp = comps[i]; 607 System.out.println(comp.getName() + "[" + comp.getImplementationVersion() + "]"); try 609 { 610 ComponentInfoImpl info = components.removeInfo(comp); 611 ComponentFiles files = components.removeFiles(comp); 612 613 if (info == null || files == null) 614 { 615 throw new TRException("The component not found in TR!" + comp); 616 } 617 618 620 if (implIndex.remove(info.toString()) == null) 621 { 622 throw new TRException("Incosistent TR (implIndex)! The component not found!" + info); 623 } 624 625 627 AssemblyDescriptorImpl ad = null; 628 try 629 { 630 ad = new AssemblyDescriptorImpl(files.getAssemblyDescriptorFile()); 631 } 632 catch (Exception e) 633 { 634 throw new TRException("Exception thrown when creating the assembly descriptor!\n" + e, e); 635 } 636 Map cdl = ad.getCDLEntities(); 637 for (Iterator javaNames = cdl.keySet().iterator(); javaNames.hasNext();) 638 { 639 String key = (String) javaNames.next(); 640 String value = (String) cdl.get(key); 641 642 if (interfaces) 643 { 644 ifaceIndex.remove(value); 645 continue; 646 } 647 else 648 { 649 String ifaceDir = (String) ifaceIndex.get(value); 651 String connPath = key.replace('.', File.separatorChar); 652 String connName = File.separator + connPath + ".class"; 653 files.getFiles().remove(connName); 654 } 655 } 656 657 Enumeration enumFiles = files.getFiles().elements(); 659 660 while (enumFiles.hasMoreElements()) 661 { 662 File file = (File)enumFiles.nextElement(); 663 file.delete(); 664 Tools.deleteEmptyDirectoryTree(file.getParentFile(), null); } 666 670 } 671 catch (TRException tre) 672 { 673 try 674 { 675 saveProperties(); 676 } 677 catch (IOException e) 678 { 679 throw new TRException("Exception thrown when saving properties in exception handler!\n" + e + "\nHandled exception:" + tre); 680 } 681 throw tre; 682 } 683 684 try 685 { 686 saveProperties(); 687 } 688 catch (IOException e) 689 { 690 throw new TRException("Exception thrown when saving properties!\n" + e); 691 } 692 693 } 694 } 695 System.out.println("End ------------------------------------------------------"); } 697 698 699 private ComponentInfoImpl[] getTransitiveClosure (ComponentInfo[] comps) { 700 if (comps == null) 701 return null; 702 List list = new LinkedList(); 704 Set set = new HashSet(); 706 707 for (int i = 0; i < comps.length; i++) { 708 ComponentInfoImpl comp = components.getInfo(comps[i]); if (comp == null) comp = new ComponentInfoImpl(comps[i].getName(), comps[i].getImplementationVersion()); 710 list.add(comp); 711 set.add(comp); 712 } 713 714 for (int i = 0; i < list.size(); i++) { 715 ComponentInfoImpl info = (ComponentInfoImpl) list.get(i); 716 ComponentInfo[] subs = info.getSubComponents(); 717 if (subs != null) { 718 for (int j = 0; j < subs.length; j++) { 719 ComponentInfo sub = components.getInfo(subs[j]); 720 if (sub != null && !set.contains(sub)) { list.add(sub); 722 set.add(sub); 723 } 724 } 725 } 726 } 727 728 return (ComponentInfoImpl[]) list.toArray(new ComponentInfoImpl[list.size()]); 729 } 730 731 739 public synchronized boolean contains (ComponentInfo desc) { 740 return components.contains(desc); 741 } 742 743 753 public synchronized boolean containsComponent (ComponentInfo comp, boolean inferiors) 754 { 755 ComponentInfo[] comps; 756 757 ComponentInfo[] tmpComps = new ComponentInfo[1]; 758 tmpComps[0] = comp; 759 760 if (inferiors) comps = getTransitiveClosure(tmpComps); 761 else comps = tmpComps; 762 for (int i = 0; i < comps.length; i++) 763 { 764 ComponentInfo info = comps[i]; 765 ComponentFiles files = components.getFiles(info); 766 if (files == null) return false; 767 } 768 769 return true; 770 } 771 772 776 public Bundle list () { 777 Set infos = components.getInfos(); 778 ComponentInfo[] descs = (ComponentInfo[]) infos.toArray(new ComponentInfo[infos.size()]); 779 return getBundle(descs, null, false); 780 } 781 782 } 783 | Popular Tags |