1 19 20 package org.netbeans.modules.j2ee.ddloaders.app; 21 22 import java.awt.Component ; 23 import java.awt.Dialog ; 24 import java.awt.event.*; 25 import java.io.*; 26 import java.util.*; 27 import javax.swing.JButton ; 28 import javax.swing.event.ChangeListener ; 29 30 import org.openide.DialogDescriptor; 31 import org.openide.filesystems.*; 32 import org.openide.loaders.*; 33 import org.openide.nodes.*; 34 import org.openide.util.HelpCtx; 35 import org.openide.util.RequestProcessor; 36 37 import org.xml.sax.*; 38 import org.openide.ErrorManager; 39 import org.openide.util.NbBundle; 40 41 import org.netbeans.modules.j2ee.ddloaders.common.xmlutils.SAXParseError; 42 import org.netbeans.modules.j2ee.dd.api.application.*; 43 import org.netbeans.api.xml.cookies.ValidateXMLCookie; 44 import org.netbeans.spi.xml.cookies.*; 45 import org.openide.DialogDisplayer; 46 import org.netbeans.modules.j2ee.dd.impl.application.ApplicationProxy; 47 48 import org.netbeans.api.java.project.JavaProjectConstants; 50 import org.netbeans.api.project.FileOwnerQuery; 51 import org.netbeans.api.project.Project; 52 import org.netbeans.api.project.ProjectUtils; 53 import org.netbeans.api.project.ProjectInformation; 54 55 import org.netbeans.api.project.SourceGroup; 57 import org.netbeans.api.project.Sources; 58 import org.netbeans.modules.j2ee.ddloaders.common.DD2beansDataObject; 59 60 61 65 public class EarDataObject extends DD2beansDataObject 66 implements DDChangeListener, ApplicationProxy.OutputProvider, FileChangeListener, ChangeListener { 67 private Application ejbJar; 68 private FileObject srcRoots[]; 69 protected final static RequestProcessor RP = new RequestProcessor("XML Parsing"); 71 private static final long serialVersionUID = 8857563089355069362L; 72 73 74 public static final String PROP_DOCUMENT_DTD = "documentDTD"; 76 77 private boolean unparsable=true; 78 79 80 private Vector updates; 81 82 private RequestProcessor.Task updateTask; 83 private FileObjectObserver fileListener; 84 85 private static final int HOME = 10; 86 private static final int REMOTE = 20; 87 private static final int LOCAL_HOME = 30; 88 private static final int LOCAL = 40; 89 90 public EarDataObject (FileObject pf, EarDataLoader loader) throws DataObjectExistsException { 91 super (pf, loader); 92 init (pf,loader); 93 } 94 public boolean isRenameAllowed(){ 95 return false; 96 } 97 public boolean isUnparsable(){ 98 return unparsable; 99 } 100 101 private void init (FileObject fo,EarDataLoader loader) { 102 InputSource in = DataObjectAdapters.inputSource(this); 104 ValidateXMLCookie validateCookie = new ValidateXMLSupport(in); 105 getCookieSet().add(validateCookie); 106 107 108 109 fileListener = new FileObjectObserver(fo); 110 111 Project project = FileOwnerQuery.getOwner (getPrimaryFile ()); 112 if (project != null) { 113 Sources sources = ProjectUtils.getSources(project); 114 sources.addChangeListener (this); 115 } 116 refreshSourceFolders (); 117 } 118 119 private void refreshSourceFolders () { 120 ArrayList srcRootList = new ArrayList (); 121 122 Project project = FileOwnerQuery.getOwner (getPrimaryFile ()); 123 if (project != null) { 124 Sources sources = ProjectUtils.getSources(project); 125 sources.addChangeListener (this); 126 SourceGroup[] groups = sources.getSourceGroups(JavaProjectConstants.SOURCES_TYPE_JAVA); 127 for (int i = 0; i < groups.length; i++) { 128 org.netbeans.modules.j2ee.api.ejbjar.EjbJar ejbModule = org.netbeans.modules.j2ee.api.ejbjar.EjbJar.getEjbJar(groups[i].getRootFolder()); 129 if ((ejbModule != null) && (ejbModule.getDeploymentDescriptor() != null)) { 130 try { 131 FileObject fo = groups [i].getRootFolder (); 132 srcRootList.add (groups [i].getRootFolder ()); 133 FileSystem fs = fo.getFileSystem (); 134 fs.removeFileChangeListener(this); fs.addFileChangeListener (this); 136 } catch (FileStateInvalidException ex) { 137 ErrorManager.getDefault ().notify (ex); 138 } 139 } 140 } 141 } 142 srcRoots = (FileObject []) srcRootList.toArray (new FileObject [srcRootList.size ()]); 143 } 144 145 private String getPackageName (FileObject clazz) { 146 for (int i = 0; i < srcRoots.length; i++) { 147 String rp = FileUtil.getRelativePath (srcRoots [i], clazz); 148 if (rp != null) { 149 if (clazz.getExt ().length () > 0) { 150 rp = rp.substring (0, rp.length () - clazz.getExt ().length () - 1); 151 } 152 return rp.replace ('/', '.'); 153 } 154 } 155 return null; 156 } 157 158 public Application getApplication(){ 159 if (ejbJar==null){ 160 parsingDocument(); 161 } 162 return ejbJar; 163 } 164 165 public Application getOriginalApplication() throws IOException { 166 return DDProvider.getDefault().getDDRoot(getPrimaryFile()); 167 } 168 169 protected org.openide.nodes.Node createNodeDelegate () { 170 return new EarDataNode(this); 171 } 172 173 174 179 protected String getIconBaseForValidDocument() { 180 return "org/netbeans/modules/j2ee/ddloaders/ejb/DDDataIcon.gif"; } 182 183 188 protected String getIconBaseForInvalidDocument() { 189 return "org/netbeans/modules/j2ee/ddloaders/ejb/DDDataIcon1.gif"; } 191 192 195 public String getStringForValidDocument() { 196 return NbBundle.getMessage (EarDataObject.class, "LAB_deploymentDescriptor"); 197 } 198 199 203 public String getStringForInvalidDocument(SAXParseError error) { 204 return NbBundle.getMessage (EarDataObject.class, "TXT_errorOnLine", new Integer (error.getErrorLine())); 205 } 206 207 210 protected String generateDocument() { 211 ByteArrayOutputStream out = new ByteArrayOutputStream(); 213 try { 214 ejbJar.write(out); 215 out.close(); 216 return out.toString("UTF8"); } 218 catch (IOException e) { 219 ErrorManager.getDefault ().notify(org.openide.ErrorManager.INFORMATIONAL, e); 220 } 221 catch (IllegalStateException e){ 222 ErrorManager.getDefault ().notify(org.openide.ErrorManager.INFORMATIONAL, e); 223 } 224 return out.toString (); 225 } 226 227 231 protected String updateDocument(javax.swing.text.Document doc) { 232 return null; 233 } 234 236 public void write(Application ejbJarProxy) throws IOException { 237 Application app = getApplication(); 238 if (app!=null) { 239 app.merge(ejbJarProxy,Application.MERGE_UNION); 240 } 241 setNodeDirty(true); 242 } 243 245 public FileObject getTarget() { 246 return getPrimaryFile(); 247 } 248 249 protected SAXParseError updateNode(InputSource is) throws IOException { 250 if (ejbJar==null) { 252 try { 253 ejbJar = DDProvider.getDefault().getDDRoot(getPrimaryFile()); 254 firePropertyChange(Node.PROP_PROPERTY_SETS,null,null); 255 if (unparsable) { 256 unparsable=false; 257 } 258 return null; 259 } catch (RuntimeException e) { 260 if (!unparsable) { 261 unparsable=true; 262 } 263 return new SAXParseError(new SAXParseException(e.getMessage(),new org.xml.sax.helpers.LocatorImpl ())); 264 } 265 } 266 Application app=null; 267 try { 268 app = EarDDUtils.createApplication(is); 269 if (!ejbJar.getVersion().equals(app.getVersion())) { 270 ((ApplicationProxy)ejbJar).setOriginal(app); 271 } 272 unparsable=false; 273 if (app.getError()!= null) { 274 System.out.println(app.getError().getMessage()); 276 } 277 } catch (SAXParseException e) { 278 if (!unparsable) { 279 unparsable=true; 280 } 281 return new SAXParseError(e); 282 } catch (SAXException e) { 283 if (!unparsable) { 284 unparsable=true; 285 } 286 throw new IOException(); 287 } 288 if (app!=null){ 289 ejbJar.merge(app,org.netbeans.modules.schema2beans.BaseBean.MERGE_UPDATE); 291 292 } 293 return null; 294 } 295 296 305 321 protected DataObject handleCopy(DataFolder f) throws IOException { 322 DataObject dObj = super.handleCopy(f); 323 try { dObj.setValid(false); }catch(java.beans.PropertyVetoException e){} 324 return dObj; 325 } 326 327 protected void dispose () { 328 synchronized (this) { 330 updates = null; 331 if (updateTask != null) { 332 updateTask.cancel(); 333 } 334 } 335 super.dispose (); 336 } 337 338 341 347 348 351 public void deploymentChange (DDChangeEvent evt) { 352 356 synchronized (this) { 357 if (updates == null) { 358 updates = new Vector (); 359 } 360 updates.addElement (evt); 361 } 362 363 if (updateTask == null) { 365 updateTask = RequestProcessor.getDefault().post (new Runnable () { 366 public void run () { 367 java.util.List changes = null; 368 synchronized (EarDataObject.this) { 369 if (!EarDataObject.this.isValid()) 370 return; 371 if (updates != null) { 372 changes = updates; 373 updates = null; 374 } 375 } 376 if (changes != null) 377 showDDChangesDialog (changes); 378 } 379 }, 2000, Thread.MIN_PRIORITY); 380 } 381 else { 382 updateTask.schedule (2000); 383 } 384 } 385 386 398 private void showDDChangesDialog (List changes) { 399 final JButton processButton; 400 final JButton processAllButton; 401 final JButton closeButton; 402 final DDChangesPanel connectionPanel; 403 final DialogDescriptor confirmChangesDescriptor; 404 final Dialog confirmChangesDialog[] = { null }; 405 406 processButton = new JButton (NbBundle.getMessage (EarDataObject.class, "LAB_processButton")); 407 processButton.setMnemonic (NbBundle.getMessage (EarDataObject.class, "LAB_processButton_Mnemonic").charAt (0)); 408 processButton.setToolTipText (NbBundle.getMessage (EarDataObject.class, "ACS_processButtonA11yDesc")); 409 processAllButton = new JButton (NbBundle.getMessage (EarDataObject.class, "LAB_processAllButton")); 410 processAllButton.setMnemonic (NbBundle.getMessage (EarDataObject.class, "LAB_processAllButton_Mnemonic").charAt (0)); 411 processAllButton.setToolTipText (NbBundle.getMessage (EarDataObject.class, "ACS_processAllButtonA11yDesc")); 412 closeButton = new JButton (NbBundle.getMessage (EarDataObject.class, "LAB_closeButton")); 413 closeButton.setMnemonic (NbBundle.getMessage (EarDataObject.class, "LAB_closeButton_Mnemonic").charAt (0)); 414 closeButton.setToolTipText (NbBundle.getMessage (EarDataObject.class, "ACS_closeButtonA11yDesc")); 415 final Object [] options = new Object [] { 416 processButton, 417 processAllButton 418 }; 419 final Object [] additionalOptions = new Object [] { 420 closeButton 421 }; 422 423 String fsname = ""; Project project = FileOwnerQuery.getOwner (getPrimaryFile ()); 425 if (project != null) { 426 String projectName = null; 427 ProjectInformation projectInfo = ProjectUtils.getInformation(project); 428 if(projectInfo != null){ 429 fsname = projectInfo.getName(); 430 } 431 } 432 433 String caption = NbBundle.getMessage (EarDataObject.class, "MSG_SynchronizeCaption", fsname); 438 connectionPanel = new DDChangesPanel (caption, processButton); 439 confirmChangesDescriptor = new DialogDescriptor ( 440 connectionPanel, 441 NbBundle.getMessage (EarDataObject.class, "LAB_ConfirmDialog"), 442 true, 443 options, 444 processButton, 445 DialogDescriptor.RIGHT_ALIGN, 446 HelpCtx.DEFAULT_HELP, 447 new ActionListener () { 448 public void actionPerformed (ActionEvent e) { 449 if (e.getSource () instanceof Component ) { 450 Component root; 451 452 root = javax.swing.SwingUtilities.getRoot ((Component )e.getSource ()); 454 if (!root.isDisplayable ()) { 455 return; 456 } 457 } 458 if (options[0].equals (e.getSource ())) { 459 int min = connectionPanel.changesList.getMinSelectionIndex (); 460 int max = connectionPanel.changesList.getMaxSelectionIndex (); 461 for (int i = max; i >= min; i--) { 462 if (connectionPanel.changesList.isSelectedIndex (i)) { 463 final DDChangeEvent ev = (DDChangeEvent)connectionPanel.listModel.getElementAt (i); 464 processDDChangeEvent (ev); 465 connectionPanel.listModel.removeElementAt (i); 466 } 467 } 468 if (connectionPanel.listModel.isEmpty ()) { 469 confirmChangesDialog[0].setVisible (false); 470 } 471 else { 472 processButton.setEnabled (false); 473 } 474 } 475 else if (options[1].equals (e.getSource ())) { 476 Enumeration en = connectionPanel.listModel.elements (); 477 while (en.hasMoreElements ()) { 478 processDDChangeEvent ((DDChangeEvent)en.nextElement ()); 479 } 480 confirmChangesDialog[0].setVisible (false); 481 connectionPanel.setChanges (null); 482 } 483 else if (additionalOptions[0].equals (e.getSource ())) { 484 confirmChangesDialog[0].setVisible (false); 485 connectionPanel.setChanges (null); 486 } 487 } 488 } 489 ); 490 confirmChangesDescriptor.setAdditionalOptions (additionalOptions); 491 492 processButton.setEnabled (false); 493 processAllButton.requestFocus (); 494 connectionPanel.setChanges (changes); 495 496 try { 497 confirmChangesDialog[0] = DialogDisplayer.getDefault ().createDialog (confirmChangesDescriptor); 498 confirmChangesDialog[0].setVisible(true); 499 } finally { 500 confirmChangesDialog[0].dispose (); 501 } 502 } 503 504 private void processDDChangeEvent (DDChangeEvent evt) { 505 if (!isValid()) 506 return; 507 508 if (evt.getType () == DDChangeEvent.EJB_ADDED) { 509 String clz = evt.getNewValue (); 510 511 String urimapping = "/servlet/"+clz; } else { 515 updateDD(evt.getOldValue(), (String )evt.getNewValue (), evt.getType()); 516 } 517 } 518 519 public HelpCtx getHelpCtx() { 520 return new HelpCtx(EarDataObject.class); 521 } 522 523 private RequestProcessor.Task elementTask; 524 private List deletedEjbNames; 525 private List newFileNames; 526 527 private void elementCreated(final String elementName) { 528 synchronized (this) { 529 if (newFileNames==null) { 530 newFileNames=new ArrayList(); 531 } 532 newFileNames.add(elementName); 533 } 534 535 if (elementTask == null) { 536 elementTask = RequestProcessor.getDefault().post (new Runnable () { 537 public void run () { 538 if (deletedEjbNames!=null) { 539 for (int i=0;i<deletedEjbNames.size();i++) { 540 String deletedServletName = (String )deletedEjbNames.get(i); 541 String deletedName=deletedServletName; 542 int index = deletedServletName.lastIndexOf("."); if (index>0) deletedName = deletedServletName.substring(index+1); 544 boolean found = false; 545 for (int j=0;j<newFileNames.size();j++) { 546 String newFileName = (String )newFileNames.get(j); 547 String newName = newFileName; 548 int ind = newFileName.lastIndexOf("."); if (ind>0) newName = newFileName.substring(ind+1); 550 if (deletedName.equals(newName)) { found=true; 552 DDChangeEvent ddEvent = 553 new DDChangeEvent(EarDataObject.this,EarDataObject.this,deletedServletName,newFileName,DDChangeEvent.EJB_CHANGED); 554 deploymentChange (ddEvent); 555 synchronized (EarDataObject.this) { 556 newFileNames.remove(newFileName); 557 } 558 break; 559 } 560 } 561 if (!found) { 562 DDChangeEvent ddEvent = 563 new DDChangeEvent(EarDataObject.this,EarDataObject.this,null,deletedServletName,DDChangeEvent.EJB_DELETED); 564 deploymentChange (ddEvent); 565 } 566 } synchronized (EarDataObject.this) { 568 deletedEjbNames=null; 569 } 570 } 572 synchronized (EarDataObject.this) { 573 newFileNames=null; 574 } 575 576 } 578 }, 1500, Thread.MIN_PRIORITY); 579 } 580 else { 581 elementTask.schedule (1500); 582 } 583 } 584 585 public void fileRenamed(org.openide.filesystems.FileRenameEvent fileRenameEvent) { 586 589 FileObject fo = fileRenameEvent.getFile(); 590 String resourceName = getPackageName (fo); 591 if (resourceName != null) { 592 int index = resourceName.lastIndexOf("."); String oldName = fileRenameEvent.getName(); 594 String oldResourceName = (index>=0?resourceName.substring(0,index+1):"")+oldName; 595 Application ejbJar = getApplication(); 596 if (ejbJar.getStatus()==Application.STATE_VALID) { 597 fireEvent(oldResourceName, resourceName, DDChangeEvent.EJB_CHANGED); 598 612 } 613 } 614 } 615 616 public void fileFolderCreated(org.openide.filesystems.FileEvent fileEvent) { 617 } 618 619 public void fileDeleted(org.openide.filesystems.FileEvent fileEvent) { 620 623 FileObject fo = fileEvent.getFile(); 624 String resourceName = getPackageName (fo); 625 if (resourceName != null) { 626 boolean foundElement=false; 627 if (newFileNames==null) { 628 foundElement = 629 fireEvent(null, resourceName, DDChangeEvent.EJB_DELETED); 630 631 650 } else { 651 if (foundElement) return; 665 666 692 } 693 } 694 } 695 696 public void fileDataCreated(org.openide.filesystems.FileEvent fileEvent) { 697 FileObject fo = fileEvent.getFile(); 698 String resourceName = getPackageName (fo); 699 if (resourceName != null) { 700 elementCreated(resourceName); 701 } 702 } 703 704 public void fileChanged(org.openide.filesystems.FileEvent fileEvent) { 705 } 706 707 public void fileAttributeChanged(org.openide.filesystems.FileAttributeEvent fileAttributeEvent) { 708 } 709 710 public void stateChanged (javax.swing.event.ChangeEvent e) { 711 refreshSourceFolders (); 712 } 713 714 716 private class FileObjectObserver implements FileChangeListener { 717 FileObjectObserver (FileObject fo) { 718 fo.addFileChangeListener((FileChangeListener)org.openide.util.WeakListeners.create( 719 FileChangeListener.class, this, fo)); 720 } 721 722 public void fileAttributeChanged(FileAttributeEvent fileAttributeEvent) { 723 } 724 725 public void fileChanged(FileEvent fileEvent) { 726 ApplicationProxy ejbJar = (ApplicationProxy) EarDataObject.this.getApplication(); 727 boolean needRewriting = true; 728 if (ejbJar!= null && ejbJar.isWriting()) { ejbJar.setWriting(false); 730 needRewriting=false; 731 } 732 if (isSavingDocument()) { setSavingDocument(false); 734 needRewriting=false; 735 } 736 if (needRewriting) getEditorSupport().restartTimer(); 737 } 738 739 public void fileDataCreated(FileEvent fileEvent) { 740 } 741 742 public void fileDeleted(FileEvent fileEvent) { 743 } 744 745 public void fileFolderCreated(FileEvent fileEvent) { 746 } 747 748 public void fileRenamed(FileRenameEvent fileRenameEvent) { 749 } 750 751 } 752 753 822 private int getSpecificEvent(int eventType, int interfaceType){ 823 if(eventType == DDChangeEvent.EJB_CHANGED){ 824 switch(interfaceType){ 825 case HOME :{ 826 return DDChangeEvent.EJB_HOME_CHANGED; 827 } 828 case REMOTE :{ 829 return DDChangeEvent.EJB_REMOTE_CHANGED; 830 } 831 case LOCAL_HOME :{ 832 return DDChangeEvent.EJB_LOCAL_HOME_CHANGED; 833 } 834 case LOCAL :{ 835 return DDChangeEvent.EJB_LOCAL_CHANGED; 836 } 837 } 838 } 839 if(eventType == DDChangeEvent.EJB_DELETED){ 840 switch(interfaceType){ 841 case HOME :{ 842 return DDChangeEvent.EJB_HOME_DELETED; 843 } 844 case REMOTE :{ 845 return DDChangeEvent.EJB_REMOTE_DELETED; 846 } 847 case LOCAL_HOME :{ 848 return DDChangeEvent.EJB_LOCAL_HOME_DELETED; 849 } 850 case LOCAL :{ 851 return DDChangeEvent.EJB_LOCAL_DELETED; 852 } 853 } 854 } 855 return -1 ; 857 } 858 859 private boolean fireEvent(String oldResourceName, String resourceName, 860 int eventType){ 861 866 boolean elementFound = false; 867 String resource = null; 868 int specificEventType = -1; 869 if(eventType == DDChangeEvent.EJB_CHANGED){ 870 resource = oldResourceName; 871 } else { 872 resource = resourceName; 873 } 874 if (elementFound) { 895 assert(specificEventType > 0); 896 DDChangeEvent ddEvent = 897 new DDChangeEvent(this,this,oldResourceName, 898 resourceName, specificEventType); 899 deploymentChange (ddEvent); 900 } 901 return elementFound; 902 } 903 904 private void updateDD(String oldResourceName, String resourceName, 905 int eventType){ 906 911 boolean ddModified = false; 912 913 switch(eventType){ 914 case DDChangeEvent.EJB_CLASS_CHANGED : { 915 if (oldResourceName == null) 917 return; 918 919 break; 925 } 926 case DDChangeEvent.EJB_CLASS_DELETED : { 927 if (resourceName == null){ 929 return; 930 } 931 932 break; 942 } 943 944 case DDChangeEvent.EJB_HOME_CHANGED : { 945 if (oldResourceName == null) 946 return; 947 948 break; 955 } 956 957 case DDChangeEvent.EJB_REMOTE_CHANGED : { 958 if (oldResourceName == null) 959 return; 960 961 break; 968 } 969 970 case DDChangeEvent.EJB_LOCAL_HOME_CHANGED : { 971 if (oldResourceName == null) 972 return; 973 974 break; 981 } 982 983 case DDChangeEvent.EJB_LOCAL_CHANGED : { 984 if (oldResourceName == null) 985 return; 986 987 break; 994 } 995 996 case DDChangeEvent.EJB_HOME_DELETED : { 997 if (resourceName == null){ 998 return; 999 } 1000 1001 break; 1008 } 1009 1010 case DDChangeEvent.EJB_REMOTE_DELETED : { 1011 if (resourceName == null){ 1012 return; 1013 } 1014 1015 break; 1022 } 1023 1024 case DDChangeEvent.EJB_LOCAL_HOME_DELETED : { 1025 if (resourceName == null){ 1026 return; 1027 } 1028 1029 break; 1036 } 1037 1038 case DDChangeEvent.EJB_LOCAL_DELETED : { 1039 if (resourceName == null){ 1040 return; 1041 } 1042 1043 break; 1050 } 1051 } 1052 1053 if(ddModified){ 1054 setNodeDirty (true); 1055 } 1056 1067 } 1075} 1076 | Popular Tags |