1 19 20 package org.netbeans.modules.j2ee.sun.share.config; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.io.File ; 25 import java.io.IOException ; 26 import java.util.ArrayList ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.Set ; 30 31 import javax.swing.text.BadLocationException ; 32 import javax.swing.text.StyledDocument ; 33 import javax.enterprise.deploy.spi.exceptions.InvalidModuleException ; 34 import javax.enterprise.deploy.spi.exceptions.ConfigurationException ; 35 36 import org.xml.sax.InputSource ; 37 38 import org.openide.DialogDisplayer; 39 import org.openide.ErrorManager; 40 import org.openide.NotifyDescriptor; 41 import org.openide.filesystems.FileObject; 42 import org.openide.filesystems.FileUtil; 43 import org.openide.filesystems.FileChangeListener; 44 import org.openide.filesystems.FileLock; 45 import org.openide.cookies.CloseCookie; 46 import org.openide.cookies.EditCookie; 47 import org.openide.cookies.EditorCookie; 48 import org.openide.cookies.OpenCookie; 49 import org.openide.cookies.PrintCookie; 50 import org.openide.cookies.SaveCookie; 51 import org.openide.loaders.DataFolder; 52 import org.openide.loaders.DataObject; 53 import org.openide.loaders.DataObjectExistsException; 54 import org.openide.loaders.MultiFileLoader; 55 import org.openide.loaders.XMLDataObject; 56 import org.openide.nodes.CookieSet; 57 import org.openide.nodes.Node; 58 import org.openide.text.DataEditorSupport; 59 import org.openide.text.NbDocument; 60 import org.openide.util.HelpCtx; 61 import org.openide.util.Mutex; 62 import org.openide.util.NbBundle; 63 import org.openide.util.WeakListeners; 64 import org.openide.windows.CloneableTopComponent; 65 import org.openide.windows.CloneableOpenSupport; 66 import org.openide.windows.TopComponent; 67 68 import org.netbeans.api.project.FileOwnerQuery; 69 import org.netbeans.api.project.Project; 70 import org.netbeans.api.xml.cookies.CheckXMLCookie; 71 import org.netbeans.api.xml.cookies.ValidateXMLCookie; 72 import org.netbeans.spi.xml.cookies.CheckXMLSupport; 73 import org.netbeans.spi.xml.cookies.DataObjectAdapters; 74 import org.netbeans.spi.xml.cookies.ValidateXMLSupport; 75 import org.netbeans.modules.xml.api.EncodingUtil; 76 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; 77 import org.netbeans.modules.j2ee.deployment.plugins.api.ConfigurationSupport; 78 import org.netbeans.modules.j2ee.sun.share.config.ui.*; 79 import org.netbeans.modules.j2ee.sun.share.configbean.SunONEDeploymentConfiguration; 80 81 82 87 public class ConfigDataObject extends XMLDataObject implements ConfigurationSaver, FileChangeListener { 88 89 92 public static final String SERVER_ID = "J2EE"; 94 private final File configKey; 95 private HashSet secondaries = null; private boolean isEdited = false; 97 private boolean isEditedChecked = false; 98 private ValidateXMLCookie validateCookie = null; 99 private CheckXMLCookie checkCookie = null; 100 private XMLEditorSupport xmlEditorSupport = null; 101 private XMLOpenSupport xmlOpenSupport = null; 102 103 106 private boolean reloadDialogOpened; 107 108 109 public ConfigDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException { 110 super(pf, loader); 111 configKey = FileUtil.toFile(pf); 112 pf.addFileChangeListener((FileChangeListener) WeakListeners.create(FileChangeListener.class, this, pf)); 114 initCookies(); 115 } 116 117 private void initCookies() { 118 CookieSet.Factory factory = new CookieSet.Factory() { 123 public Node.Cookie createCookie(Class klass) { 124 return null; 125 } 126 }; 127 128 CookieSet cookies = getCookieSet(); 131 cookies.add(EditorCookie.class, factory); 132 cookies.add(OpenCookie.class, factory); 133 cookies.add(CloseCookie.class, factory); 134 cookies.add(PrintCookie.class, factory); 135 } 136 137 public HelpCtx getHelpCtx() { 138 return new HelpCtx(getPrimaryFile().getName()+"_help"); } 140 141 public boolean isRenameAllowed() { 142 return false; 143 } 144 145 protected Node createNodeDelegate() { 146 return new ConfigDataNode(this); 147 } 148 149 protected DataObject handleCopy(DataFolder f) throws IOException { 150 DataObject newDo = super.handleCopy(f); 151 try { 152 FileObject primary = newDo.getPrimaryFile(); 153 newDo.setValid(false); 154 newDo = DataObject.find(primary); 155 } catch (java.beans.PropertyVetoException pve) { 156 } 158 return newDo; 159 } 160 161 public SunONEDeploymentConfiguration getDeploymentConfiguration() throws ConfigurationException { 162 SunONEDeploymentConfiguration config = SunONEDeploymentConfiguration.getConfiguration(configKey); 164 165 if(config == null) { 166 FileObject configFO = FileUtil.toFileObject(configKey); 168 ConfigurationSupport.requestCreateConfiguration(configFO, SERVER_ID); config = SunONEDeploymentConfiguration.getConfiguration(configKey); 170 if(config == null) { 171 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, new IllegalStateException ( 174 "Unable to initialize DeploymentConfiguration for " + configKey.getPath() + " on server " + SERVER_ID)); 175 } 176 } 177 178 return config; 179 } 180 181 184 public boolean hasSecondaries() { 185 return getSecondaries().size() > 0; 186 } 187 188 protected void addSecondary(SecondaryConfigDataObject secondary) { 189 getSecondaries().add(secondary); 190 } 191 192 protected void removeSecondary(SecondaryConfigDataObject secondary) { 193 getSecondaries().remove(secondary); 194 } 195 196 protected Set getSecondaries() { 197 if (secondaries != null) { 198 return secondaries; 199 } 200 secondaries = new HashSet (); 201 String [] paths = this.getProvider().getConfigSupport().getDeploymentConfigurationFileNames(); 202 for (int i=0; i<paths.length; i++) { 203 File path = new File (paths[i]); 204 FileObject fo = getProvider().findDeploymentConfigurationFile(path.getName()); 205 if (fo == null) { 206 continue; 207 } 208 try { 209 SecondaryConfigDataObject second = (SecondaryConfigDataObject) DataObject.find(fo); 210 secondaries.add(second); 211 } catch (Exception ex) { 212 continue; 213 } 214 } 215 return secondaries; 216 } 217 218 protected boolean isConfigEditorOpened() { 219 Boolean result = (Boolean ) Mutex.EVENT.readAccess(new Mutex.Action() { 220 public Object run() { 221 ConfigBeanTopComponent configEditor = findOpenedConfigEditor(); 222 boolean isOpen = (configEditor != null) ? configEditor.isOpened() : false; 223 return isOpen ? Boolean.TRUE : Boolean.FALSE; 224 } 225 }); 226 return result.booleanValue(); 227 } 228 229 private OpenCookie _getOpenCookie() { 230 OpenCookie myOpen = getOpenCookie(); 231 for (Iterator i=getSecondaries().iterator(); i.hasNext();) { 232 SecondaryConfigDataObject secondary = (SecondaryConfigDataObject) i.next(); 233 if (secondary.getOpenCookie() == null) { 234 return null; 235 } 236 } 237 return myOpen; 238 } 239 240 protected OpenCookie getOpenCookie() { 241 if (!Utils.isSunServer(getProvider().getServerID())) { 244 return null; 245 } 246 if (!isEditedChecked) { 247 isEdited = checkIsEdited(); 248 } 249 if (!isEdited) { 250 if (xmlOpenSupport == null) { 251 xmlOpenSupport = new XMLOpenSupport(this); 252 } 253 return xmlOpenSupport; 254 } else { 255 return null; 256 } 257 } 258 259 private EditCookie _getEditCookie() { 260 EditCookie myEdit = getEditCookie(); 261 for (Iterator i=getSecondaries().iterator(); i.hasNext();) { 262 SecondaryConfigDataObject secondary = (SecondaryConfigDataObject) i.next(); 263 if (secondary.getEditCookie() == null) { 264 return null; 265 } 266 } 267 return myEdit; 268 } 269 270 protected EditCookie getEditCookie() { 271 if (!isConfigEditorOpened()) { 272 if (xmlEditorSupport == null) { 273 xmlEditorSupport = new XMLEditorSupport(this); 274 } 275 return xmlEditorSupport; 276 } else { 277 return null; 278 } 279 } 280 281 public org.openide.nodes.Node.Cookie getCookie(Class c) { 282 Node.Cookie retValue = null; 283 if (OpenCookie.class.isAssignableFrom(c)) { 284 return _getOpenCookie(); 285 } else if (EditCookie.class.isAssignableFrom(c) 286 || EditorCookie.class.isAssignableFrom(c) 287 || CloseCookie.class.isAssignableFrom(c) 288 || PrintCookie.class.isAssignableFrom(c)) { 289 return _getEditCookie(); 290 } else if (ConfigurationStorage.class.isAssignableFrom(c)) { 291 retValue = getStorage(); 292 } else if (ValidateXMLCookie.class.isAssignableFrom(c)) { 293 if (validateCookie == null) { 294 InputSource in = DataObjectAdapters.inputSource(this); 295 validateCookie = new ValidateXMLSupport(in); 296 } 297 return validateCookie; 298 } else if (CheckXMLCookie.class.isAssignableFrom(c)) { 299 if (checkCookie == null) { 300 InputSource in = DataObjectAdapters.inputSource(this); 301 checkCookie = new CheckXMLSupport(in); 302 } 303 return checkCookie; 304 } 305 306 if (retValue == null) { 307 retValue = super.getCookie(c); 308 } 309 return retValue; 310 } 311 312 private boolean checkIsEdited() { 313 if (xmlEditorSupport != null) { 314 isEditedChecked = true; 315 return (xmlEditorSupport.getOpenedPanes() != null); 316 } 317 return false; 318 } 319 320 public void editorClosed(ConfigBeanTopComponent tc) { 321 if (xmlOpenSupport != null) { 322 xmlOpenSupport.reset(); 323 } 324 325 tc.reset(); 326 fireCookieChange(); 327 } 328 329 protected J2eeModuleProvider getProvider() { 330 FileObject f = getPrimaryFile(); 331 J2eeModuleProvider provider = null; 332 Project p = FileOwnerQuery.getOwner(f); 333 if (p != null) { 334 provider = (J2eeModuleProvider) p.getLookup().lookup(J2eeModuleProvider.class); 335 } 336 if (provider == null) { 337 throw new RuntimeException ("Project " + p + " does not provide J2eeModuleProvider in its lookup"); } 339 return provider; 340 } 341 342 protected ConfigurationStorage getStorage() { 343 ConfigurationStorage storage = null; 344 345 try { 346 SunONEDeploymentConfiguration config = getDeploymentConfiguration(); 347 if(config != null) { 348 storage = config.getStorage(); 349 } 350 } catch (ConfigurationException ex) { 351 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, ex); 352 } 353 354 return storage; 355 } 356 357 public static FileObject getRelative(FileObject from, String path) throws IOException { 358 FileObject step = from; 359 while (path.startsWith("..")) { 361 step = step.getParent(); 362 path = path.substring(2); 363 if (path.startsWith("/")) { 364 path = path.substring(1); 365 } 366 } 367 if (path.length() > 0) { 369 step = step.getFileObject(path); 370 } 371 return step; 372 } 373 374 public static String getRelativePath(FileObject from, FileObject to) { 375 String path = ""; 376 while (!FileUtil.isParentOf(from, to) || from.equals(to)) { 378 if (from.equals(to)) { 379 break; 380 } 381 path = path + "../"; 382 from = from.getParent(); 383 } 384 if (!from.equals(to)) { 386 path = path + FileUtil.getRelativePath(from, to); 387 } 388 return path; 389 } 390 391 public void resetChanged() { 392 removeSaveCookie(); 393 } 394 395 public void removeEditorChanges() { 396 if (xmlEditorSupport != null) { 397 xmlEditorSupport.notifyUnmodified(); 398 } 399 } 400 401 public void removeAllEditorChanges() { 402 removeEditorChanges(); 403 for (Iterator i = getSecondaries().iterator(); i.hasNext(); ) { 404 SecondaryConfigDataObject second = (SecondaryConfigDataObject) i.next(); 405 second.removeEditorChanges(); 406 } 407 } 408 409 410 public boolean areModified() { 411 if (isModified()) { 412 return true; 413 } 414 for (Iterator i = getSecondaries().iterator(); i.hasNext(); ) { 415 SecondaryConfigDataObject second = (SecondaryConfigDataObject) i.next(); 416 if (second.isModified()) { 417 return true; 418 } 419 } 420 return false; 421 } 422 423 424 public void resetAllChanged() { 425 resetChanged(); 426 for (Iterator i=getSecondaries().iterator(); i.hasNext();) { 427 SecondaryConfigDataObject second = (SecondaryConfigDataObject) i.next(); 428 second.resetChanged(); 429 } 430 } 431 432 public void setChanged() { 433 addSaveCookie(new S()); 434 } 435 436 public boolean isModified() { 437 return super.isModified(); 438 } 439 440 private void handleReload(FileObject fo) throws IOException , InvalidModuleException , ConfigurationException { 441 ConfigurationStorage cs = getStorage(); 442 if (cs != null && !cs.saveInProgress()) { 443 boolean doReload = true; 445 boolean doReopen = false; 446 447 if(isConfigEditorOpened()) { 448 if(isModified()) { 449 doReload = false; 450 if(!reloadDialogOpened) { 451 String message = NbBundle.getMessage(ConfigDataObject.class, "MSG_ExternalChange", fo.getName()); 452 NotifyDescriptor nd = new NotifyDescriptor.Confirmation(message, NotifyDescriptor.YES_NO_OPTION); 453 reloadDialogOpened = true; 454 455 try { 456 Object ret = DialogDisplayer.getDefault().notify(nd); 457 if(NotifyDescriptor.YES_OPTION.equals(ret)) { 458 resetChanged(); 459 closeConfigEditors(); 460 doReload = true; 461 doReopen = true; 462 } else { 463 doReload = false; 464 } 465 } finally { 466 reloadDialogOpened = false; 467 } 468 } 469 } else { 470 closeConfigEditors(); 471 doReopen = true; 472 } 473 } 474 475 if(doReload) { 477 cs.load(); 478 } 479 480 if(doReopen) { 482 Mutex.EVENT.readAccess(new Runnable () { 483 public void run() { 484 OpenCookie opener = (OpenCookie) ConfigDataObject.this.getCookie(OpenCookie.class); 486 if(opener != null) { 487 opener.open(); 488 } 489 } 490 }); 491 } 492 } 493 } 494 495 public void fileAttributeChanged(org.openide.filesystems.FileAttributeEvent fe) { 496 } 498 499 public void fileChanged(org.openide.filesystems.FileEvent fe) { 500 try { 502 if(isValid() && fe.getFile().equals(getPrimaryFile())) { 503 handleReload(fe.getFile()); 504 } 505 } catch (Exception e) { 506 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 507 } 508 } 509 510 public void fileDataCreated(org.openide.filesystems.FileEvent fe) { 511 } 513 514 public void fileDeleted(org.openide.filesystems.FileEvent fe) { 515 } 517 518 public void fileFolderCreated(org.openide.filesystems.FileEvent fe) { 519 } 521 522 public void fileRenamed(org.openide.filesystems.FileRenameEvent fe) { 523 } 525 526 protected void fireCookieChange() { 527 fireLimitedCookieChange(); 528 for (Iterator i=getSecondaries().iterator(); i.hasNext();) { 529 SecondaryConfigDataObject secondary = (SecondaryConfigDataObject) i.next(); 530 secondary.fireLimitedCookieChange(); 531 } 532 } 533 534 protected void fireLimitedCookieChange() { 535 firePropertyChange(PROP_COOKIE, null, null); 536 } 537 538 private class S implements SaveCookie { 539 public void save() throws java.io.IOException { 540 ConfigurationStorage cs = getStorage(); 545 if (cs != null) { 546 cs.save(); 547 } 548 } 549 } 550 551 protected final void addSaveCookie(SaveCookie save) { 552 getCookieSet().add(save); 553 setModified(true); 554 } 555 556 protected final void removeSaveCookie() { 557 SaveCookie sc = null; 558 while ((sc = (SaveCookie) getCookie(SaveCookie.class)) != null) { 559 getCookieSet().remove(sc); 560 } 561 this.setModified(false); 562 } 563 564 private static class XMLOpenSupport extends DataEditorSupport implements OpenCookie, PropertyChangeListener { 565 566 public XMLOpenSupport(ConfigDataObject obj) { 567 super(obj, new XMLEditorEnv(obj, OpenCookie.class)); 568 setMIMEType("text/xml"); 570 } 573 574 public void open() { 575 ConfigDataObject cdo = (ConfigDataObject) getDataObject(); 576 cdo.addPropertyChangeListener(this); 577 cdo.getPrimaryFile().refresh(); ConfigurationStorage configStorage = (ConfigurationStorage) cdo.getCookie(ConfigurationStorage.class); 579 if (configStorage == null) { 580 EditCookie editor = (EditCookie) cdo.getCookie(EditCookie.class); 581 if (editor != null) { 582 editor.edit(); 583 } 584 return; 585 } 586 587 cdo.openConfigEditor(); 595 } 596 597 protected CloneableTopComponent createCloneableTopComponent() { 598 ConfigDataObject cdo = (ConfigDataObject) getDataObject(); 599 ConfigurationStorage storage = (ConfigurationStorage) 600 cdo.getCookie(ConfigurationStorage.class); 601 return new ConfigBeanTopComponent(storage); 602 } 603 604 public void propertyChange(PropertyChangeEvent evt) { 605 if (DataObject.PROP_MODIFIED.equals(evt.getPropertyName())) { 606 final ConfigDataObject cdo = (ConfigDataObject) getDataObject(); 608 if(cdo.isValid()) { 609 final ConfigurationStorage storage = cdo.getStorage(); 610 final String newDisplayName = messageName(); 611 Mutex.EVENT.readAccess(new Runnable () { 612 public void run() { 613 Iterator it = TopComponent.getRegistry().getOpened().iterator(); 614 while (it.hasNext()) { 615 TopComponent tc = (TopComponent) it.next(); 616 if (tc instanceof ConfigBeanTopComponent) { 617 ConfigBeanTopComponent configEditor = (ConfigBeanTopComponent) tc; 618 if (configEditor.isFor(storage)) { 619 configEditor.setDisplayName(newDisplayName); 620 } 621 } 622 } 623 } 624 }); 625 } else { 626 } 628 } 629 } 630 631 public void reset() { 632 ((ConfigDataObject)getDataObject()).removePropertyChangeListener(this); 633 } 634 } 635 636 protected void openConfigEditor() { 637 ConfigurationStorage storage = getStorage(); 638 ConfigBeanTopComponent tc = findOpenedConfigEditor(storage); 639 if (tc == null) { 640 tc = new ConfigBeanTopComponent(storage); 641 } 642 643 tc.open(); 644 tc.requestActive(); 645 fireCookieChange(); 646 } 647 648 649 protected ConfigBeanTopComponent findOpenedConfigEditor() { 650 return findOpenedConfigEditor(getStorage()); 651 } 652 653 public static ConfigBeanTopComponent findOpenedConfigEditor(final ConfigurationStorage storage) { 654 ConfigBeanTopComponent result = (ConfigBeanTopComponent) Mutex.EVENT.readAccess(new Mutex.Action() { 659 public Object run() { 660 Iterator it = TopComponent.getRegistry().getOpened().iterator(); 661 while (it.hasNext()) { 662 TopComponent tc = (TopComponent) it.next(); 663 if (tc instanceof ConfigBeanTopComponent) { 664 ConfigBeanTopComponent beanTC = (ConfigBeanTopComponent) tc; 665 if (beanTC.isFor(storage)) { 666 return beanTC; 667 } 668 } 669 } 670 return null; 671 } 672 }); 673 674 return result; 675 } 676 677 706 711 public boolean closeConfigEditors() { 712 final ArrayList editorList = new ArrayList (); 713 ConfigurationStorage storage = getStorage(); 714 715 Iterator iter = TopComponent.getRegistry().getOpened().iterator(); 717 while(iter.hasNext()) { 718 Object tc = iter.next(); 719 if(tc instanceof ConfigBeanTopComponent && ((ConfigBeanTopComponent) tc).isFor(storage)) { 720 editorList.add(tc); 721 } 722 } 723 724 Boolean result = (Boolean ) Mutex.EVENT.readAccess(new Mutex.Action() { 725 public Object run() { 726 Boolean result = Boolean.TRUE; 727 Iterator iter = editorList.iterator(); 728 while(iter.hasNext()) { 729 ConfigBeanTopComponent configTC = (ConfigBeanTopComponent) iter.next(); 730 result = (configTC.close() && result.booleanValue()) ? Boolean.TRUE : Boolean.FALSE; 731 } 732 return result; 733 } 734 }); 735 736 return result.booleanValue(); 737 } 738 739 private static class XMLEditorSupport extends DataEditorSupport implements EditCookie, EditorCookie.Observable, PrintCookie, CloseCookie { 740 741 public XMLEditorSupport(ConfigDataObject obj) { 742 super(obj, new XMLEditorEnv(obj, EditCookie.class)); 743 setMIMEType("text/xml"); } 747 748 protected boolean canClose() { 749 boolean result = super.canClose(); 750 return result; 751 } 752 753 class Save implements SaveCookie { 754 public void save() throws IOException { 755 saveDocument(); 756 } 757 } 758 759 762 public void saveDocument() throws java.io.IOException { 763 final String defaultEncoding = "UTF8"; final StyledDocument doc = getDocument(); 765 String enc = EncodingUtil.detectEncoding(doc); 767 if (enc == null) { 768 enc = defaultEncoding; 769 } 770 771 try { 772 new java.io.OutputStreamWriter (new java.io.ByteArrayOutputStream (1), enc); 774 if(queryCanEncode(doc, enc)) { 775 super.saveDocument(); 776 getDataObject().setModified(false); 777 } 778 } catch(java.io.UnsupportedEncodingException ex) { 779 if(queryUpdateProlog(doc, enc, defaultEncoding)) { 780 super.saveDocument(); 781 getDataObject().setModified(false); 782 } 783 } 784 } 785 786 private boolean queryCanEncode(final StyledDocument doc, final String enc) { 787 boolean result = true; 788 try { 790 java.nio.charset.CharsetEncoder coder = java.nio.charset.Charset.forName(enc).newEncoder(); 791 if(!coder.canEncode(doc.getText(0, doc.getLength()))){ 792 NotifyDescriptor nd = new NotifyDescriptor.Confirmation( 793 NbBundle.getMessage (XMLEditorSupport.class, "MSG_BadCharConversion", new Object [] { getDataObject().getPrimaryFile().getNameExt(), enc}), 795 NotifyDescriptor.YES_NO_OPTION, 796 NotifyDescriptor.WARNING_MESSAGE); 797 nd.setValue(NotifyDescriptor.NO_OPTION); 798 DialogDisplayer.getDefault().notify(nd); 799 800 if(nd.getValue() != NotifyDescriptor.YES_OPTION) { 801 result = false; 802 } 803 } 804 } catch (javax.swing.text.BadLocationException e){ 805 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 806 } 807 return result; 808 } 809 810 private boolean queryUpdateProlog(final StyledDocument doc, final String enc, final String defaultEncoding) { 811 boolean needsSave = false; 812 813 NotifyDescriptor nd = new NotifyDescriptor.Confirmation( 815 NbBundle.getMessage(XMLEditorSupport.class, "MSG_BadEncodingDuringSave", new Object [] { getDataObject().getPrimaryFile().getNameExt(), enc, defaultEncoding}), 817 NotifyDescriptor.YES_NO_OPTION, 818 NotifyDescriptor.WARNING_MESSAGE); 819 nd.setValue(NotifyDescriptor.NO_OPTION); 820 DialogDisplayer.getDefault().notify(nd); 821 822 if(nd.getValue() == NotifyDescriptor.YES_OPTION) { 823 824 try { 826 final int MAX_PROLOG = 1000; 827 int maxPrologLen = Math.min(MAX_PROLOG, doc.getLength()); 828 final char prolog[] = doc.getText(0, maxPrologLen).toCharArray(); 829 int prologLen = 0; 831 if (prolog[0] == '<' && prolog[1] == '?' && prolog[2] == 'x') { 833 834 for (int i = 3; i<maxPrologLen; i++) { 836 if (prolog[i] == '?' && prolog[i+1] == '>') { 837 prologLen = i + 1; 838 break; 839 } 840 } 841 } 842 843 final int passPrologLen = prologLen; 844 845 Runnable edit = new Runnable () { 846 public void run() { 847 try { 848 doc.remove(0, passPrologLen + 1); doc.insertString(0, "<?xml version='1.0' encoding='" + defaultEncoding + "' ?> \n<!-- was: " + new String (prolog, 0, passPrologLen + 1) + " -->", null); } catch (BadLocationException e) { 851 if (System.getProperty("netbeans.debug.exceptions") != null) { e.printStackTrace(); 853 } 854 } 855 } 856 }; 857 858 NbDocument.runAtomic(doc, edit); 859 860 needsSave = true; 862 } catch (BadLocationException lex) { 863 org.openide.ErrorManager.getDefault().notify(lex); 864 } 865 } 866 867 return needsSave; 868 } 869 870 882 protected boolean notifyModified() { 883 if (! super.notifyModified()) { 884 return false; 885 } 886 ((ConfigDataObject) getDataObject()).addSaveCookie(new Save()); 887 return true; 888 } 889 890 protected void notifyUnmodified() { 891 super.notifyUnmodified(); 892 ((ConfigDataObject) getDataObject()).resetChanged(); 893 } 894 895 public void edit() { 896 ConfigDataObject cdo = (ConfigDataObject) getDataObject(); 897 cdo.isEdited = true; 898 open(); 899 cdo.fireCookieChange(); 900 } 901 902 protected void notifyClosed() { 903 super.notifyClosed(); 904 ConfigDataObject cdo = (ConfigDataObject) getDataObject(); 905 cdo.isEdited = false; 906 cdo.fireCookieChange(); 907 } 908 909 public void refreshDocument() { 910 super.reloadDocument(); 911 } 912 } 913 914 private static class XMLEditorEnv extends DataEditorSupport.Env { 917 private static final long serialVersionUID = 6593415381104273008L; 918 919 private final Class openSupportCookieClass; 920 921 public XMLEditorEnv(ConfigDataObject dobj, Class cookieClass) { 922 super(dobj); 923 openSupportCookieClass = cookieClass; 924 } 925 protected FileObject getFile() { 926 return getDataObject().getPrimaryFile(); 927 } 928 protected FileLock takeLock() throws IOException { 929 return ((ConfigDataObject) getDataObject()).getPrimaryEntry().takeLock(); 930 } 931 public CloneableOpenSupport findCloneableOpenSupport() { 932 return (CloneableOpenSupport) getDataObject().getCookie(openSupportCookieClass); 935 } 936 } 937 } 938 | Popular Tags |