1 19 20 package org.netbeans.core.windows.persistence; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.io.ByteArrayInputStream ; 25 import java.io.FileNotFoundException ; 26 import java.io.IOException ; 27 import java.io.InputStream ; 28 import java.io.InvalidObjectException ; 29 import java.io.NotSerializableException ; 30 import java.lang.ref.Reference ; 31 import java.lang.ref.WeakReference ; 32 import java.lang.reflect.Method ; 33 import java.util.ArrayList ; 34 import java.util.Collections ; 35 import java.util.Enumeration ; 36 import java.util.HashMap ; 37 import java.util.HashSet ; 38 import java.util.Iterator ; 39 import java.util.List ; 40 import java.util.Locale ; 41 import java.util.Map ; 42 import java.util.Set ; 43 import java.util.WeakHashMap ; 44 import java.util.logging.Level ; 45 import java.util.logging.Logger ; 46 import org.netbeans.core.windows.Debug; 47 import org.openide.cookies.InstanceCookie; 48 import org.openide.cookies.SaveCookie; 49 import org.openide.filesystems.FileLock; 50 import org.openide.filesystems.FileObject; 51 import org.openide.filesystems.FileUtil; 52 import org.openide.filesystems.Repository; 53 import org.openide.loaders.DataFolder; 54 import org.openide.loaders.DataObject; 55 import org.openide.loaders.DataObjectNotFoundException; 56 import org.openide.loaders.InstanceDataObject; 57 import org.openide.modules.ModuleInfo; 58 import org.openide.modules.SpecificationVersion; 59 import org.openide.util.Exceptions; 60 import org.openide.util.Lookup; 61 import org.openide.util.NbBundle; 62 import org.openide.util.io.SafeException; 63 import org.openide.windows.TopComponent; 64 import org.openide.xml.XMLUtil; 65 import org.xml.sax.EntityResolver ; 66 import org.xml.sax.InputSource ; 67 import org.xml.sax.SAXException ; 68 import org.xml.sax.XMLReader ; 69 import org.xml.sax.helpers.DefaultHandler ; 70 71 77 public final class PersistenceManager implements PropertyChangeListener { 78 79 static final Logger LOG = Logger.getLogger("org.netbeans.core.windows.persistence"); 81 82 83 static final String ROOT_MODULE_FOLDER = "Windows2"; public static final String ROOT_LOCAL_FOLDER = "Windows2Local"; static final String WINDOWMANAGER_FOLDER = "WindowManager"; static final String GROUPS_FOLDER = "Groups"; static final String MODES_FOLDER = "Modes"; public static final String COMPS_FOLDER = "Components"; 90 91 public static final String WINDOWMANAGER_EXT = "wswmgr"; public static final String WORKSPACE_EXT = "wswksp"; public static final String MODE_EXT = "wsmode"; public static final String TCREF_EXT = "wstcref"; public static final String GROUP_EXT = "wsgrp"; public static final String TCGROUP_EXT = "wstcgrp"; public static final String COMPONENT_EXT = "settings"; 99 100 private static final String DEFAULT_TC_NAME = "untitled_tc"; 102 private static final boolean DEBUG = Debug.isLoggable(PersistenceManager.class); 103 104 105 private FileObject rootModuleFolder; 106 107 private FileObject rootLocalFolder; 108 109 110 private FileObject compsModuleFolder; 111 112 113 private FileObject groupsModuleFolder; 114 115 private FileObject groupsLocalFolder; 116 117 118 private FileObject modesModuleFolder; 119 120 private FileObject modesLocalFolder; 121 122 123 private WindowManagerParser windowManagerParser; 124 125 126 private ModuleChangeHandler changeHandler; 127 128 129 private final Map <TopComponent, String > topComponent2IDMap = new WeakHashMap <TopComponent, String >(30); 131 132 133 private final Map <TopComponent, String > topComponentNonPersistent2IDMap = 135 new WeakHashMap <TopComponent, String >(30); 136 137 139 private Set <String > globalIDSet = new HashSet <String >(30); 140 141 142 private final Map <String , Reference <TopComponent>> id2TopComponentMap = 143 Collections.synchronizedMap(new HashMap <String , Reference <TopComponent>>(30)); 144 145 146 private final Map <String , Reference <TopComponent>> id2TopComponentNonPersistentMap = 147 Collections.synchronizedMap(new HashMap <String , Reference <TopComponent>>(30)); 148 149 151 private final Map <DataObject, String > dataobjectToTopComponentMap = 152 new WeakHashMap <DataObject, String >(30); 153 154 155 private Set invalidIds = new HashSet (10); 156 157 160 private final Set <String > usedTcIds = new HashSet <String >(10); 162 163 private final Object LOCK_IDS = new Object (); 164 165 166 private XMLReader parser; 167 168 private static PersistenceManager defaultInstance; 169 170 171 private PersistenceManager() { 172 } 173 174 176 public static synchronized PersistenceManager getDefault() { 177 if(defaultInstance == null) { 178 defaultInstance = new PersistenceManager(); 179 } 180 181 return defaultInstance; 182 } 183 184 public void reset() { 185 rootModuleFolder = null; 186 rootLocalFolder = null; 187 compsModuleFolder = null; 188 groupsModuleFolder = null; 189 groupsLocalFolder = null; 190 modesModuleFolder = null; 191 modesLocalFolder = null; 192 windowManagerParser = null; 193 if (changeHandler != null) { 194 changeHandler.stopHandling(); 195 } 196 changeHandler = null; 197 } 198 199 200 public void clear() { 201 reset(); 202 topComponent2IDMap.clear(); 203 topComponentNonPersistent2IDMap.clear(); 204 globalIDSet = new HashSet <String >(30); 205 id2TopComponentMap.clear(); 206 id2TopComponentNonPersistentMap.clear(); 207 dataobjectToTopComponentMap.clear(); 208 invalidIds = new HashSet (10); 209 usedTcIds.clear(); 210 } 211 212 FileObject getRootModuleFolder () throws IOException { 213 try { 214 if (rootModuleFolder == null) { 215 rootModuleFolder = FileUtil.createFolder( 216 Repository.getDefault().getDefaultFileSystem().getRoot(), ROOT_MODULE_FOLDER 217 ); 218 } 219 return rootModuleFolder; 220 } catch (IOException exc) { 221 String annotation = NbBundle.getMessage(PersistenceManager.class, 222 "EXC_RootFolder", ROOT_MODULE_FOLDER); 223 Exceptions.attachLocalizedMessage(exc, annotation); 224 throw exc; 225 } 226 } 227 228 FileObject getRootLocalFolder () throws IOException { 229 try { 230 if (rootLocalFolder == null) { 231 rootLocalFolder = FileUtil.createFolder( 232 Repository.getDefault().getDefaultFileSystem().getRoot(), ROOT_LOCAL_FOLDER 233 ); 234 } 235 return rootLocalFolder; 236 } catch (IOException exc) { 237 String annotation = NbBundle.getMessage(PersistenceManager.class, 238 "EXC_RootFolder", ROOT_LOCAL_FOLDER); 239 Exceptions.attachLocalizedMessage(exc, annotation); 240 throw exc; 241 } 242 } 243 244 247 void setRootModuleFolder (FileObject rootModuleFolder) { 248 this.rootModuleFolder = rootModuleFolder; 249 } 250 251 254 void setRootLocalFolder (FileObject rootLocalFolder) { 255 this.rootLocalFolder = rootLocalFolder; 256 } 257 258 259 public FileObject getComponentsModuleFolder () throws IOException { 260 try { 261 if (compsModuleFolder == null) { 262 compsModuleFolder = FileUtil.createFolder( 263 getRootModuleFolder(), COMPS_FOLDER 264 ); 265 } 266 return compsModuleFolder; 267 } catch (IOException exc) { 268 String annotation = NbBundle.getMessage(PersistenceManager.class, 269 "EXC_CompsFolder", COMPS_FOLDER); 270 Exceptions.attachLocalizedMessage(exc, annotation); 271 throw exc; 272 } 273 } 274 275 277 public FileObject getComponentsLocalFolder () throws IOException { 278 try { 279 FileObject compsLocalFolder = FileUtil.createFolder( 280 getRootLocalFolder(), COMPS_FOLDER 281 ); 282 return compsLocalFolder; 283 } catch (IOException exc) { 284 String annotation = NbBundle.getMessage(PersistenceManager.class, 285 "EXC_CompsFolder", COMPS_FOLDER); 286 Exceptions.attachLocalizedMessage(exc, annotation); 287 throw exc; 288 } 289 } 290 291 292 public FileObject getGroupsModuleFolder () throws IOException { 293 try { 294 if (groupsModuleFolder == null) { 295 groupsModuleFolder = FileUtil.createFolder( 296 getRootModuleFolder(), GROUPS_FOLDER 297 ); 298 } 299 return groupsModuleFolder; 300 } catch (IOException exc) { 301 String annotation = NbBundle.getMessage(PersistenceManager.class, 302 "EXC_GroupsFolder", GROUPS_FOLDER); 303 Exceptions.attachLocalizedMessage(exc, annotation); 304 throw exc; 305 } 306 } 307 308 309 public FileObject getGroupsLocalFolder () throws IOException { 310 try { 311 if (groupsLocalFolder == null) { 312 groupsLocalFolder = FileUtil.createFolder( 313 getRootLocalFolder(), GROUPS_FOLDER 314 ); 315 } 316 return groupsLocalFolder; 317 } catch (IOException exc) { 318 String annotation = NbBundle.getMessage(PersistenceManager.class, 319 "EXC_GroupsFolder", GROUPS_FOLDER); 320 Exceptions.attachLocalizedMessage(exc, annotation); 321 throw exc; 322 } 323 } 324 325 326 public FileObject getModesModuleFolder () throws IOException { 327 try { 328 if (modesModuleFolder == null) { 329 modesModuleFolder = FileUtil.createFolder( 330 getRootModuleFolder(), MODES_FOLDER 331 ); 332 } 333 return modesModuleFolder; 334 } catch (IOException exc) { 335 String annotation = NbBundle.getMessage(PersistenceManager.class, 336 "EXC_ModesFolder", MODES_FOLDER); 337 Exceptions.attachLocalizedMessage(exc, annotation); 338 throw exc; 339 } 340 } 341 342 343 public FileObject getModesLocalFolder () throws IOException { 344 try { 345 if (modesLocalFolder == null) { 346 modesLocalFolder = FileUtil.createFolder( 347 getRootLocalFolder(), MODES_FOLDER 348 ); 349 } 350 return modesLocalFolder; 351 } catch (IOException exc) { 352 String annotation = NbBundle.getMessage(PersistenceManager.class, 353 "EXC_ModesFolder", MODES_FOLDER); 354 Exceptions.attachLocalizedMessage(exc, annotation); 355 throw exc; 356 } 357 } 358 359 361 public void propertyChange (PropertyChangeEvent evt) { 362 if (DataObject.PROP_COOKIE.equals(evt.getPropertyName())) { 363 Object obj = evt.getSource(); 364 removeTopComponentForDataObject((DataObject)obj); 365 } 366 } 367 368 private void removeTopComponentForDataObject(DataObject dob) { 369 InstanceCookie ic = (InstanceCookie)dob.getCookie(InstanceCookie.class); 372 if (ic == null) { 374 synchronized(LOCK_IDS) { 375 String tc_id = (String ) dataobjectToTopComponentMap.remove(dob); 376 if (tc_id != null) { 377 382 WeakReference result = (WeakReference )id2TopComponentMap.remove(tc_id); 384 if (result != null) { 385 TopComponent tc = (TopComponent)result.get(); 386 if (tc != null) { 387 topComponent2IDMap.remove(tc); 388 } 389 } 390 } 391 } 392 } 393 } 394 395 401 public String getGlobalTopComponentID (TopComponent tc, String preferredID) { 402 synchronized(LOCK_IDS) { 403 String result = (String ) topComponent2IDMap.get(tc); 405 if (result != null) { 406 if (isInvalidId(result)) { 407 restorePair(tc, result); 408 } 409 return result; 410 } 411 result = (String ) topComponentNonPersistent2IDMap.get(tc); 412 if (result != null) { 413 return result; 414 } 415 } 416 417 if (isTopComponentProbablyPersistent(tc)) { 419 try { 420 return createTopComponentPersistentID(tc, preferredID); 421 } catch (IOException exc) { 422 LOG.log(Level.WARNING, "[Winsys.PersistenceManager.getGlobalTopComponentID]: Cannot create TC ID", exc); return createTopComponentNonPersistentID(tc, preferredID); 424 } 425 } else { 426 return createTopComponentNonPersistentID(tc, preferredID); 427 } 428 } 429 430 433 public void removeGlobalTopComponentID(String id) { 434 synchronized(LOCK_IDS) { 436 globalIDSet.remove(id.toUpperCase(Locale.ENGLISH)); 437 WeakReference result = (WeakReference )id2TopComponentMap.remove(id); 438 if (result != null) { 439 TopComponent tc = (TopComponent)result.get(); 440 if (tc != null) { 441 topComponent2IDMap.remove(tc); 442 } 443 } 444 result = (WeakReference )id2TopComponentNonPersistentMap.remove(id); 445 if (result != null) { 446 TopComponent tc = (TopComponent)result.get(); 447 if (tc != null) { 448 topComponentNonPersistent2IDMap.remove(tc); 449 } 450 } 451 } 452 } 453 454 457 private TopComponent getTopComponentPersistentForID(String stringId) { 458 synchronized(LOCK_IDS) { 459 WeakReference result = (WeakReference )id2TopComponentMap.get(stringId); 461 if (result != null) { 462 TopComponent tc = (TopComponent)result.get(); 463 if (tc != null) { 464 return tc; 465 } else { 466 id2TopComponentMap.remove(stringId); 468 } 469 } 470 } 471 IOException resultExc = null; 473 try { 474 DataObject dob = findTopComponentDataObject(getComponentsLocalFolder(), stringId); 475 if (dob == null) { 476 dob = findTopComponentDataObject(getComponentsModuleFolder(), stringId); 479 } 480 if (dob != null) { 481 InstanceCookie ic = (InstanceCookie)dob.getCookie(InstanceCookie.class); 482 if (ic != null) { 483 TopComponent tc = (TopComponent)ic.instanceCreate(); 484 synchronized(LOCK_IDS) { 485 topComponent2IDMap.put(tc, stringId); 486 id2TopComponentMap.put(stringId, new WeakReference <TopComponent>(tc)); 487 dataobjectToTopComponentMap.put(dob, stringId); 488 } 489 dob.addPropertyChangeListener(this); 490 return tc; 491 } else { 492 String excAnnotation = NbBundle.getMessage( 495 PersistenceManager.class, "EXC_BrokenTCSetting", 496 stringId); 497 resultExc = new SafeException(new IOException (excAnnotation)); 498 LOG.log(Level.WARNING, 499 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + excAnnotation, resultExc); 502 } 503 } 504 else { 505 String excAnnotation = NbBundle.getMessage(PersistenceManager.class, 507 "EXC_FailedLocateTC", stringId); 508 resultExc = new FileNotFoundException (excAnnotation); 509 LOG.warning( 510 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + excAnnotation); 513 } 518 } catch (NoClassDefFoundError ndfe) { LOG.log(Level.WARNING, 520 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + ndfe.getMessage(), ndfe); 523 } catch (InvalidObjectException ioe) { 524 LOG.log(Level.WARNING, 525 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + ioe.getMessage(), ioe); 528 } catch (DataObjectNotFoundException dnfe) { 529 LOG.log(Level.WARNING, 530 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + " Object not found: " + dnfe.getMessage() + ". It was probably deleted.", dnfe); } catch (ClassNotFoundException exc) { 535 LOG.log(Level.WARNING, 538 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + exc.getMessage(), exc); 541 } catch (ClassCastException exc) { 542 LOG.log(Level.WARNING, 545 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + exc.getMessage(), exc); 548 } catch (IOException ioe) { 549 LOG.log(Level.WARNING, 550 "[WinSys.PersistenceManager.getTopComponentForID]" + " Problem when deserializing TopComponent for tcID:'" + stringId + "'. Reason: " + ioe.getMessage(), ioe); 553 } 554 return null; 555 } 556 557 560 private TopComponent getTopComponentNonPersistentForID (String stringId) { 561 synchronized(LOCK_IDS) { 562 WeakReference result = (WeakReference ) id2TopComponentNonPersistentMap.get(stringId); 564 if (result != null) { 565 TopComponent tc = (TopComponent) result.get(); 566 if (tc != null) { 567 return tc; 568 } else { 569 id2TopComponentNonPersistentMap.remove(stringId); 571 } 572 } 573 return null; 574 } 575 } 576 577 580 public TopComponent getTopComponentForID (String stringId) { 581 TopComponent tc = getTopComponentNonPersistentForID(stringId); 582 if (tc == null) { 583 return getTopComponentPersistentForID(stringId); 584 } else { 585 return tc; 586 } 587 } 588 589 594 private static DataObject findTopComponentDataObject(FileObject folder, String name) throws IOException { 595 FileObject fo = folder.getFileObject(name, "settings"); if (fo == null) { 598 fo = folder.getFileObject(name, "ser"); } 600 if (fo == null) { 601 fo = folder.getFileObject(name, "xml"); } 603 604 if (fo != null) { 605 return DataObject.find(fo); 606 } 607 608 Enumeration e = folder.getChildren(false); 613 while (e.hasMoreElements()) { 614 fo = (FileObject)e.nextElement(); 615 DataObject dob = DataObject.find(fo); 616 if (dob.getName().equals(name)) return dob; 617 } 618 DataFolder dfolder = DataFolder.findFolder(folder); 621 e = dfolder.children(); 622 while (e.hasMoreElements()) { 623 DataObject dob = (DataObject)e.nextElement(); 624 if (dob.getName().equals(name)) return dob; 625 } 626 return null; 628 } 629 630 640 private boolean isTopComponentProbablyPersistent (TopComponent tc) { 641 int persistenceType = tc.getPersistenceType(); 642 if (TopComponent.PERSISTENCE_NEVER == persistenceType) { 643 return false; 644 } 645 return true; 646 } 647 648 654 public boolean isTopComponentPersistent (TopComponent tc) { 655 int persistenceType = tc.getPersistenceType(); 656 if ((TopComponent.PERSISTENCE_NEVER == persistenceType) 657 || ((TopComponent.PERSISTENCE_ONLY_OPENED == persistenceType) && !tc.isOpened())) { 658 return false; 659 } 660 return true; 661 } 662 663 665 private void saveTopComponents (WindowManagerConfig wmc) { 666 DataFolder compsFolder; 667 try { 668 compsFolder = DataFolder.findFolder(getComponentsLocalFolder()); 669 } catch (IOException exc) { 670 LOG.log(Level.WARNING, 671 "[WinSys.PersistenceManager.saveTopComponents]" + " Cannot get components folder", exc); return; 674 } 675 Map <String , Reference <TopComponent>> copyIdToTopComponentMap; 676 synchronized(LOCK_IDS) { 678 copyIdToTopComponentMap = new HashMap <String , Reference <TopComponent>>(id2TopComponentMap); 679 } 680 681 for (Map.Entry <String , Reference <TopComponent>> curEntry: copyIdToTopComponentMap.entrySet()) { 682 TopComponent curTC = curEntry.getValue().get(); 683 if (curTC != null) { 684 try { 685 FileObject fo = compsFolder.getPrimaryFile ().getFileObject 687 (curEntry.getKey (), "settings"); DataObject ido = null; 689 if (fo != null) { 690 ido = DataObject.find(fo); 691 } 692 if (ido == null) { 693 InstanceDataObject.create( 695 compsFolder, unescape(curEntry.getKey()), curTC, null 696 ); 697 } else { 698 SaveCookie sc = (SaveCookie)ido.getCookie(SaveCookie.class); 700 if (sc != null) { 701 sc.save(); 702 } else { 703 ido.delete(); 704 InstanceDataObject.create( 705 compsFolder, unescape((String )curEntry.getKey()), curTC, null 706 ); 707 } 708 } 709 } catch (NotSerializableException nse) { 710 String id = (String ) topComponent2IDMap.get(curTC); 712 LOG.log(Level.WARNING, "TopComponent " + id + " is not serializable.", nse); removeTCFromConfig(wmc,id); 715 } catch (IOException exc) { 716 LOG.log(Level.WARNING, null, exc); 718 String id = (String ) topComponent2IDMap.get(curTC); 719 removeTCFromConfig(wmc,id); 720 } catch (RuntimeException exc) { 721 String annotation = NbBundle.getMessage( 723 PersistenceManager.class,"EXC_CannotSaveTCSettings", 724 curTC.getName()); 725 Exceptions.attachLocalizedMessage(exc, annotation); 726 LOG.log(Level.WARNING, null, exc); 727 String id = (String ) topComponent2IDMap.get(curTC); 728 removeTCFromConfig(wmc,id); 729 } catch (LinkageError le) { 730 String annotation = NbBundle.getMessage( 731 PersistenceManager.class,"EXC_CannotSaveTCSettings", 732 curTC.getName()); 733 Exceptions.attachLocalizedMessage(le, annotation); 734 LOG.log(Level.WARNING, null, le); 735 String id = (String ) topComponent2IDMap.get(curTC); 736 removeTCFromConfig(wmc,id); 737 } 738 } 739 } 740 } 741 742 743 private static FileObject findTopComponentRefFile (FileObject folder, String tcId) { 744 FileObject result = folder.getFileObject(tcId, TCREF_EXT); 745 if (result != null) { 746 return result; 747 } 748 FileObject[] childrenArray = folder.getChildren(); 749 for (int i = 0; i < childrenArray.length; i++) { 750 if (childrenArray[i].isFolder()) { 751 result = findTopComponentRefFile(childrenArray[i], tcId); 752 if (result != null) { 753 return result; 754 } 755 } 756 } 757 return null; 758 } 759 760 765 private static String escape(String name) { 766 try { 767 Method escape = 768 InstanceDataObject.class.getDeclaredMethod( 769 "escapeAndCut", new Class [] {String .class}); escape.setAccessible(true); 771 return (String ) escape.invoke(null, name); 772 } catch (Exception ex) { 773 LOG.log(Level.WARNING, 774 "Escape support failed", ex); return name; 776 } 777 } 778 779 784 private static String unescape(String name) { 785 try { 786 Method unescape = 787 InstanceDataObject.class.getDeclaredMethod( 788 "unescape", new Class [] {String .class}); unescape.setAccessible(true); 790 return (String ) unescape.invoke(null, name); 791 } catch (Exception ex) { 792 LOG.log(Level.WARNING, 793 "Escape support failed", ex); return name; 795 } 796 } 797 798 private String createTopComponentNonPersistentID (TopComponent tc, String preferredID) { 799 String compName = preferredID != null ? preferredID : null; 800 if ((compName == null) || (compName.length() == 0)) { 802 compName = DEFAULT_TC_NAME; 803 } 804 boolean isUsed = true; 806 compName = escape(compName); 807 String srcName = compName; 808 int i = 1; 809 synchronized(LOCK_IDS) { 810 while (isUsed) { 811 isUsed = false; 812 if (globalIDSet.contains(srcName.toUpperCase(Locale.ENGLISH))) { 813 isUsed = true; 814 srcName = compName + "_" + i; 815 i++; 816 } 817 } 818 819 topComponentNonPersistent2IDMap.put(tc, srcName); 820 id2TopComponentNonPersistentMap.put(srcName, new WeakReference <TopComponent>(tc)); 821 globalIDSet.add(srcName.toUpperCase(Locale.ENGLISH)); 822 } 823 824 return srcName; 825 } 826 827 private String createTopComponentPersistentID (TopComponent tc, String preferredID) throws IOException { 828 String compName = preferredID != null ? preferredID : null; 829 if ((compName == null) || (compName.length() == 0)) { 831 compName = DEFAULT_TC_NAME; 832 } 833 boolean isUsed = true; 835 String origName = compName; 836 compName = escape(compName); 837 String srcName = compName; 838 int i = 1; 839 synchronized(LOCK_IDS) { 840 while (isUsed) { 841 isUsed = false; 842 String uniqueName = FileUtil.findFreeFileName( 843 getComponentsLocalFolder(), srcName, "settings" ); 845 846 if (!srcName.equals(uniqueName) || globalIDSet.contains(uniqueName.toUpperCase(Locale.ENGLISH))) { 847 isUsed = true; 848 srcName = escape(origName + "_" + i); 850 i++; 851 } 852 853 } 854 855 topComponent2IDMap.put(tc, srcName); 856 id2TopComponentMap.put(srcName, new WeakReference <TopComponent>(tc)); 857 globalIDSet.add(srcName.toUpperCase(Locale.ENGLISH)); 858 } 859 860 return srcName; 861 } 862 863 864 private String restorePair (TopComponent tc, String id) { 865 FileObject compsFO = null; 868 try { 869 compsFO = getComponentsLocalFolder(); 870 } catch (IOException exc) { 871 LOG.log(Level.WARNING, 872 "[WinSys.PersistenceManager.restorePair]" + " Cannot get components folder", exc); return null; 875 } 876 FileObject fo = compsFO.getFileObject(id, "settings"); 877 if (fo != null) { 878 synchronized(LOCK_IDS) { 882 id2TopComponentMap.put(id, new WeakReference <TopComponent>(tc)); 883 validateId(id); 884 } 885 return id; 886 } else { 887 return null; 888 } 889 } 890 891 private boolean isInvalidId (String id) { 892 return invalidIds.contains(id); 893 } 894 895 private void validateId (String id) { 896 if (invalidIds != null) { 897 invalidIds.remove(id); 898 } 899 } 900 901 903 private Map <Exception , String > failedCompsMap; 904 905 909 public void annotatePersistenceError(Exception exc, String tcName) { 910 if (failedCompsMap == null) { 911 failedCompsMap = new HashMap <Exception , String >(); 912 } 913 failedCompsMap.put(exc, tcName); 914 } 915 916 920 public void checkPersistenceErrors(boolean reading) { 921 if(failedCompsMap == null || failedCompsMap.isEmpty()) { 922 return; 923 } 924 925 for(Iterator it = failedCompsMap.keySet().iterator(); it.hasNext(); ) { 926 Exception e = (Exception )it.next(); 927 Object name = failedCompsMap.get(e); 928 String message = NbBundle.getMessage(PersistenceManager.class, 930 (reading ? "FMT_TCReadError" : "FMT_TCWriteError"), 931 new Object [] {name}); 932 Exceptions.attachLocalizedMessage(e, message); 933 LOG.log(Level.WARNING, null, e); 934 } 935 936 failedCompsMap = null; 938 } 939 940 941 public WindowManagerParser getWindowManagerParser () { 942 if (windowManagerParser == null) { 943 windowManagerParser = new WindowManagerParser(this, WINDOWMANAGER_FOLDER); 944 } 945 return windowManagerParser; 946 } 947 948 954 public XMLReader getXMLParser (DefaultHandler h) throws SAXException { 955 if (parser == null) { 956 parser = XMLUtil.createXMLReader(); 958 parser.setEntityResolver(new EntityResolver () { 959 961 public InputSource resolveEntity (String publicId, String systemId) 962 throws SAXException { 963 if (ModeParser.INSTANCE_DTD_ID_1_0.equals(publicId) 964 || ModeParser.INSTANCE_DTD_ID_1_1.equals(publicId) 965 || ModeParser.INSTANCE_DTD_ID_1_2.equals(publicId) 966 || ModeParser.INSTANCE_DTD_ID_2_0.equals(publicId) 967 || ModeParser.INSTANCE_DTD_ID_2_1.equals(publicId) 968 || ModeParser.INSTANCE_DTD_ID_2_2.equals(publicId) 969 || ModeParser.INSTANCE_DTD_ID_2_3.equals(publicId) 970 || GroupParser.INSTANCE_DTD_ID_2_0.equals(publicId) 971 || TCGroupParser.INSTANCE_DTD_ID_2_0.equals(publicId) 972 || TCRefParser.INSTANCE_DTD_ID_1_0.equals(publicId) 973 || TCRefParser.INSTANCE_DTD_ID_2_0.equals(publicId) 974 || TCRefParser.INSTANCE_DTD_ID_2_1.equals(publicId) 975 || TCRefParser.INSTANCE_DTD_ID_2_2.equals(publicId) 976 || WindowManagerParser.INSTANCE_DTD_ID_1_0.equals(publicId) 977 || WindowManagerParser.INSTANCE_DTD_ID_1_1.equals(publicId) 978 || WindowManagerParser.INSTANCE_DTD_ID_2_0.equals(publicId) 979 || WindowManagerParser.INSTANCE_DTD_ID_2_1.equals(publicId)) { 980 InputStream is = new ByteArrayInputStream (new byte[0]); 981 return new InputSource (is); 982 } 983 return null; } 985 }); 986 } 987 parser.setContentHandler(h); 988 parser.setErrorHandler(h); 989 return parser; 990 } 991 992 995 public void addUsedTCId (String tc_id) { 996 synchronized(LOCK_IDS) { 997 usedTcIds.add(tc_id); 998 } 999 } 1000 1001 1004 public void removeUsedTCId (String tc_id) { 1005 synchronized(LOCK_IDS) { 1006 usedTcIds.remove(tc_id); 1007 } 1008 } 1009 1010 1012 public boolean isUsedTCId (String tc_id) { 1013 synchronized(LOCK_IDS) { 1014 return usedTcIds.contains(tc_id); 1015 } 1016 } 1017 1018 1021 private void checkUsedTCId () throws IOException { 1022 FileObject [] files = getComponentsLocalFolder().getChildren(); 1023 for (int i = 0; i < files.length; i++) { 1024 if (!files[i].isFolder() && "settings".equals(files[i].getExt())) { String tc_id = files[i].getName(); 1026 boolean contains; 1027 synchronized(LOCK_IDS) { 1028 contains = usedTcIds.contains(tc_id); 1029 } 1030 if (!contains) { 1031 deleteOneFO(files[i]); 1032 } 1033 } 1034 } 1035 files = getComponentsLocalFolder().getChildren(); 1037 for (int i = 0; i < files.length; i++) { 1038 if (!files[i].isFolder() && "settings".equals(files[i].getExt())) { String tc_id = files[i].getName(); 1040 synchronized(LOCK_IDS) { 1041 globalIDSet.add(tc_id.toUpperCase(Locale.ENGLISH)); 1042 } 1043 } 1044 } 1045 } 1046 1047 1050 public WindowManagerConfig loadWindowSystem () throws IOException { 1051 1053 synchronized (LOCK_IDS) { 1055 usedTcIds.clear(); 1056 } 1057 1058 copySettingsFiles(); 1059 1060 WindowManagerParser wmParser = getWindowManagerParser(); 1061 WindowManagerConfig wmc = wmParser.load(); 1062 1063 checkUsedTCId(); 1065 1066 if (changeHandler == null) { 1067 changeHandler = new ModuleChangeHandler(); 1068 changeHandler.startHandling(); 1069 } 1070 parser = null; 1072 return wmc; 1076 } 1077 1078 1081 public void saveWindowSystem (WindowManagerConfig wmc) { 1082 WindowManagerParser wmParser = getWindowManagerParser(); 1084 try { 1085 saveTopComponents(wmc); 1087 1091 wmParser.save(wmc); 1093 } catch (IOException exc) { 1097 LOG.log(Level.WARNING, null, exc); 1098 } 1099 } 1100 1101 1104 private void removeTCFromConfig (WindowManagerConfig wmc, String id) { 1105 boolean removeFromRecent = false; 1106 for (int i = 0; i < wmc.tcIdViewList.length; i++) { 1107 if (id.equals(wmc.tcIdViewList[i])) { 1108 removeFromRecent = true; 1109 break; 1110 } 1111 } 1112 if (removeFromRecent) { 1113 List <String > l = new ArrayList <String >(wmc.tcIdViewList.length); 1114 for (int i = 0; i < wmc.tcIdViewList.length; i++) { 1115 if (!id.equals(wmc.tcIdViewList[i])) { 1116 l.add(wmc.tcIdViewList[i]); 1117 } 1118 } 1119 wmc.tcIdViewList = l.toArray(new String [l.size()]); 1120 } 1121 for (int i = 0; i < wmc.modes.length; i++) { 1122 ModeConfig mc = wmc.modes[i]; 1123 if (id.equals(mc.selectedTopComponentID)) { 1124 mc.selectedTopComponentID = ""; 1125 } 1126 if (id.equals(mc.previousSelectedTopComponentID)) { 1127 mc.previousSelectedTopComponentID = ""; 1128 } 1129 boolean removeFromMode = false; 1130 for (int j = 0; j < mc.tcRefConfigs.length; j++) { 1131 if (id.equals(mc.tcRefConfigs[j].tc_id)) { 1132 removeFromMode = true; 1133 break; 1134 } 1135 } 1136 if (removeFromMode) { 1137 List <TCRefConfig> l = new ArrayList <TCRefConfig>(mc.tcRefConfigs.length); 1138 for (int j = 0; j < mc.tcRefConfigs.length; j++) { 1139 if (!id.equals(mc.tcRefConfigs[j].tc_id)) { 1140 l.add(mc.tcRefConfigs[j]); 1141 } 1142 } 1143 mc.tcRefConfigs = l.toArray(new TCRefConfig[l.size()]); 1144 } 1145 } 1146 for (int i = 0; i < wmc.groups.length; i++) { 1147 GroupConfig gc = wmc.groups[i]; 1148 boolean removeFromGroup = false; 1149 for (int j = 0; j < gc.tcGroupConfigs.length; j++) { 1150 if (id.equals(gc.tcGroupConfigs[j].tc_id)) { 1151 removeFromGroup = true; 1152 break; 1153 } 1154 } 1155 if (removeFromGroup) { 1156 List <TCGroupConfig> l = new ArrayList <TCGroupConfig>(gc.tcGroupConfigs.length); 1157 for (int j = 0; j < gc.tcGroupConfigs.length; j++) { 1158 if (!id.equals(gc.tcGroupConfigs[j].tc_id)) { 1159 l.add(gc.tcGroupConfigs[j]); 1160 } 1161 } 1162 gc.tcGroupConfigs = l.toArray(new TCGroupConfig[l.size()]); 1163 } 1164 } 1165 } 1166 1167 1168 private void copySettingsFiles () throws IOException { 1169 if (DEBUG) Debug.log(PersistenceManager.class, "copySettingsFiles ENTER"); 1172 Set <String > localSet = new HashSet <String >(100); 1173 FileObject [] filesLocal = getComponentsLocalFolder().getChildren(); 1174 for (int i = 0; i < filesLocal.length; i++) { 1175 if (!filesLocal[i].isFolder() && "settings".equals(filesLocal[i].getExt())) { localSet.add(filesLocal[i].getName()); 1177 } 1178 } 1179 1180 FileObject [] filesModule = getComponentsModuleFolder().getChildren(); 1181 for (int i = 0; i < filesModule.length; i++) { 1182 if (!filesModule[i].isFolder() && "settings".equals(filesModule[i].getExt())) { if (!localSet.contains(filesModule[i].getName())) { 1184 copySettingsFile(filesModule[i]); 1185 } 1186 } 1187 } 1188 if (DEBUG) Debug.log(PersistenceManager.class, "copySettingsFiles LEAVE"); 1189 } 1193 1194 1196 private void copySettingsFile (FileObject fo) throws IOException { 1197 if (DEBUG) Debug.log(PersistenceManager.class, "copySettingsFile fo:" + fo); 1198 FileObject destFolder = getComponentsLocalFolder(); 1199 try { 1200 fo.copy(destFolder,fo.getName(),fo.getExt()); 1201 } catch (IOException exc) { 1202 String annotation = NbBundle.getMessage(PersistenceManager.class, 1203 "EXC_CopyFails", destFolder); 1204 Exceptions.attachLocalizedMessage(exc, annotation); 1205 LOG.log(Level.WARNING, null, exc); 1206 } 1207 } 1208 1209 1212 void copySettingsFileIfNeeded (FileObject fo) throws IOException { 1213 FileObject localSettingsFO = getComponentsLocalFolder().getFileObject(fo.getNameExt()); 1214 if (localSettingsFO == null) { 1215 copySettingsFile(fo); 1216 } 1217 } 1218 1219 1220 public static void deleteOneFO (FileObject fo) { 1221 FileLock lock = null; 1222 if (fo.isValid()) { 1223 try { 1224 lock = fo.lock(); 1225 fo.delete(lock); 1226 } catch (IOException ex) { 1227 Exceptions.printStackTrace(ex); 1228 } finally { 1229 if (lock != null) { 1230 lock.releaseLock(); 1231 } 1232 } 1233 } 1234 } 1235 1236 1237 1249 static final ModuleInfo findModule (String codeNameBase, String strRelease, String strSpec) { 1250 SpecificationVersion spec = null; 1251 int release = -1; 1252 1253 if(strRelease != null) { 1254 try { 1255 release = Integer.parseInt(strRelease); 1256 } catch(NumberFormatException nfe) { 1257 LOG.log(Level.WARNING, null, nfe); 1258 } 1259 } 1260 if(strSpec != null) { 1261 spec = new SpecificationVersion(strSpec); 1262 } 1263 1264 Lookup.Result<ModuleInfo> modulesResult = 1265 Lookup.getDefault().lookup(new Lookup.Template<ModuleInfo>(ModuleInfo.class)); 1266 for (ModuleInfo curInfo: modulesResult.allInstances()) { 1267 if (curInfo.getCodeNameBase().equals(codeNameBase)) { 1270 if((release < 0 && spec == null) 1271 || (curInfo.getCodeNameRelease() > release)) { 1272 return curInfo; 1273 } else if(release < 0 1274 || curInfo.getCodeNameRelease() == release) { 1275 if(spec == null 1276 || curInfo.getSpecificationVersion().compareTo(spec) >= 0) { 1277 return curInfo; 1278 } 1279 } 1280 } 1281 } 1282 return null; 1283 } 1284 1285 1288 public static String escapeTcId4XmlContent (String tcName) { 1289 if (tcName.indexOf('&') != -1 || tcName.indexOf('\'') != -1) { 1290 tcName = tcName.replaceAll("&", "&"); 1291 tcName = tcName.replaceAll("'", "'"); 1292 } 1293 return tcName; 1294 } 1295 1296} 1297 | Popular Tags |