1 19 20 package org.netbeans.modules.java; 21 22 import java.beans.PropertyChangeEvent ; 23 import java.beans.PropertyChangeListener ; 24 import java.beans.PropertyVetoException ; 25 import java.io.IOException ; 26 import java.io.ObjectInputStream ; 27 import java.util.*; 28 import org.netbeans.api.java.classpath.ClassPath; 29 import org.netbeans.jmi.javamodel.JavaClass; 30 import org.netbeans.jmi.javamodel.JavaModelPackage; 31 import org.netbeans.jmi.javamodel.Resource; 32 import org.netbeans.modules.java.bridge.DefaultLangModel; 33 import org.netbeans.modules.java.bridge.LangModel; 34 import org.netbeans.modules.java.bridge.SrcElementImpl; 35 import org.netbeans.modules.java.parser.JavaParser; 36 import org.netbeans.modules.javacore.internalapi.JavaMetamodel; 37 import org.netbeans.modules.javacore.jmiimpl.javamodel.ResourceClassImpl; 38 import org.openide.ErrorManager; 39 import org.openide.cookies.*; 40 import org.openide.filesystems.*; 41 import org.openide.loaders.*; 42 import org.openide.nodes.AbstractNode; 43 import org.openide.nodes.CookieSet; 44 import org.openide.nodes.Node; 45 import org.openide.src.*; 46 import org.openide.src.nodes.ElementNodeFactory; 47 import org.openide.src.nodes.FilterFactory; 48 import org.openide.text.CloneableEditorSupport; 49 import org.openide.util.*; 50 51 55 public class JavaDataObject extends MultiDataObject implements CookieSet.Factory { 56 57 static final long serialVersionUID = -6035788991669336965L; 58 59 63 transient private JavaEditor editorSupport; 64 65 transient protected AbstractNode alteranteParent; 66 67 70 transient private FileChangeListener fileChangeListener; 71 72 74 transient private FileChangeListener fileChangeListenerHook; 75 76 77 80 transient private String previousFileName; 81 82 84 transient private Object lock; 85 86 private transient boolean initialized; 87 88 92 private transient JavaParserGlue parserGlue; 93 94 private transient SourceElement source = null; 95 96 private transient DefaultLangModel model = null; 97 98 102 public JavaDataObject(FileObject pf, MultiFileLoader loader) throws DataObjectExistsException { 103 super(pf, loader); 104 init(); 105 } 106 107 private void readObject(ObjectInputStream in) throws IOException , ClassNotFoundException { 108 in.defaultReadObject(); 109 init(); 110 } 111 112 private void init() { 113 MultiDataObject.Entry entry = getPrimaryEntry(); 114 CookieSet cookies = getCookieSet(); 115 Class [] cookieClasses = new Class [] { 116 JavaEditor.class, 117 JavaParser.class, 118 SourceCookie.Editor.class, 119 }; 120 cookies.add(cookieClasses, this); 121 122 PrimaryListener l = new PrimaryListener(); 123 addPropertyChangeListener(l); 124 fileChangeListenerHook = l; 125 fileChangeListener = FileUtil.weakFileChangeListener(fileChangeListenerHook, entry.getFile()); 126 lock = new Object (); 127 addSourceChangeListener(null); 128 initialized = true; 129 } 137 138 public synchronized DefaultLangModel getModel () { 139 if (model == null) { 140 synchronized (lock) { 141 if (model == null) 142 model = new DefaultLangModel (this); 143 } 144 } 145 return model; 146 } 147 148 149 void firePropertyChange0(String s, Object v1, Object v2) { 150 super.firePropertyChange(s, v1, v2); 151 } 152 153 156 private JavaParser initializeParsingSupport() { 157 if (parserGlue != null) 158 return parserGlue.getParser(); 159 synchronized (lock) { 160 if (parserGlue != null) { 161 return parserGlue.getParser(); 162 } 163 164 parserGlue = new JavaParserGlue(getPrimaryEntry()); 165 if (editorSupport != null) { 166 parserGlue.cloneableSupportCreated(editorSupport); 167 } 168 } 169 return parserGlue.getParser(); 170 } 171 172 public void setValid(boolean v) throws PropertyVetoException { 173 super.setValid(v); 174 if (!v) { 175 synchronized (this) { 176 if (parserGlue != null) { 177 parserGlue.suspendDocumentChanges(); 178 } 179 } 180 } 181 } 182 183 188 protected CloneableEditorSupport findCloneableEditorSupport() { 189 return (JavaEditor)getCookie(JavaEditor.class); 190 } 192 193 198 void addSourceChangeListener(FileObject previousPrimary) { 199 if (previousPrimary != null) { 200 previousPrimary.removeFileChangeListener(fileChangeListener); 201 } 202 getPrimaryEntry().getFile().addFileChangeListener(fileChangeListener); 203 } 204 205 void addSaveCookie(SaveCookie save) { 206 getCookieSet().add(save); 207 } 208 209 void removeSaveCookie(SaveCookie save) { 210 getCookieSet().remove(save); 211 } 212 213 public void resumeSupports() { 214 parserGlue.resumeDocumentChanges(); 215 } 216 217 public void suspendSupports() { 218 initializeParsingSupport(); 221 parserGlue.suspendDocumentChanges(); 223 } 224 225 boolean isJavaFileReadOnly() { 226 FileObject primary = getPrimaryFile(); 227 if (!isValid() || !primary.isValid()) { 228 return true; 229 } 230 return !primary.canWrite(); 231 } 232 233 235 protected DataObject handleCopy(DataFolder df) throws IOException { 236 String originalName = getName(); 237 DataObject dob = super.handleCopy(df); 238 if (!Repository.getDefault().getDefaultFileSystem().equals(dob.getPrimaryFile().getFileSystem())) { 239 JavaMetamodel.getDefaultRepository().beginTrans(true); 240 boolean fail = true; 241 try { 242 ClassPath cp = ClassPath.getClassPath(dob.getPrimaryFile(),ClassPath.SOURCE); 243 if (cp!=null) { 244 JavaModelPackage model = JavaMetamodel.getManager().resolveJavaExtent(cp.findOwnerRoot(dob.getPrimaryFile())); 245 if (model == null) { 246 ErrorManager.getDefault().log(ErrorManager.WARNING, "JavaDataObject: Extent for " + dob.getName() + " not found"); 247 fail = false; 248 return dob; 249 } 250 ResourceClassImpl resClass = (ResourceClassImpl) model.getResource(); 251 String resourceName = cp.getResourceName(dob.getPrimaryFile()); 252 Resource res = resClass.resolveResource(resourceName, true, false); 253 254 res.setPackageName(cp.getResourceName(df.getPrimaryFile()).replace('/','.')); 255 Iterator i = res.getClassifiers().iterator(); 256 while (i.hasNext()) { 257 JavaClass clazz = (JavaClass) i.next(); 258 if (clazz.getSimpleName().equals(originalName)) { 259 clazz.setSimpleName(dob.getName()); 260 } 261 } 262 } 263 fail = false; 264 } finally { 265 JavaMetamodel.getDefaultRepository().endTrans(fail); 266 } 267 } 268 return dob; 269 } 270 271 273 protected FileObject handleRename (String name) throws IOException { 274 if (!"package-info".equals(name) && !Utilities.isJavaIdentifier(name)) throw new IOException (NbBundle.getMessage(JavaDataObject.class, "FMT_Not_Valid_FileName", name)); 276 277 FileObject fo = super.handleRename(name); 278 return fo; 279 } 280 281 288 protected FileObject handleMove (DataFolder df) throws IOException { 289 FileObject f = super.handleMove(df); 290 SrcElementImpl src = (SrcElementImpl) getSource().getCookie(SrcElementImpl.class); 291 src.invalidateDelegate(); 292 return f; 293 } 294 295 298 protected DataObject handleCreateFromTemplate (DataFolder df, String name) throws IOException { 299 if (name == null) { 300 name = FileUtil.findFreeFileName(df.getPrimaryFile(), 302 getPrimaryFile().getName(), "java"); } else if (!"package-info".equals(name) && !Utilities.isJavaIdentifier(name)) throw new IOException (NbBundle.getMessage(JavaDataObject.class, "FMT_Not_Valid_FileName", name)); 305 306 IndentFileEntry entry = (IndentFileEntry)getPrimaryEntry(); 307 entry.initializeIndentEngine(); 308 DataObject obj; 309 310 boolean failed = true; 311 JavaMetamodel.getDefaultRepository().beginTrans(true); 312 try { 313 obj = createDataObject(df, name); 314 ClassPath cp = ClassPath.getClassPath(df.getPrimaryFile(),ClassPath.SOURCE); 315 if (cp != null) { 316 String packageName = cp.getResourceName (df.getPrimaryFile(),'.',false); 317 assert packageName != null; 318 JavaModelPackage model = JavaMetamodel.getManager().resolveJavaExtent(cp.findOwnerRoot (obj.getPrimaryFile())); 320 ResourceClassImpl resClass = (ResourceClassImpl) model.getResource(); 321 String resourceName = cp.getResourceName (obj.getPrimaryFile()); 322 Resource res = resClass.resolveResource(resourceName, true, false); 323 res.setName(resourceName); 324 Iterator i = res.getClassifiers().iterator(); 325 if (i.hasNext()) { 326 JavaClass clazz = (JavaClass) i.next(); 327 clazz.setSimpleName(name); 328 } 329 if (!"".equals(res.getPackageName())) { 331 res.setPackageName(packageName); 332 } 333 } 334 else { 335 ErrorManager.getDefault().log ("Can not update source while creating from template, destination folder "+ 339 df.getPrimaryFile().getPath()+" is not in any project."); } 341 failed = false; 342 } finally { 343 JavaMetamodel.getDefaultRepository().endTrans(failed); 344 entry.setIndentEngine(null); 345 } 346 return obj; 347 } 348 349 356 private DataObject createDataObject(DataFolder df, String name) throws IOException { 357 DataObject obj = super.handleCreateFromTemplate(df, name); 358 359 try { 361 obj.setValid(false); 362 obj = DataObject.find(obj.getPrimaryFile()); 363 } catch (PropertyVetoException e) { 364 } 366 return obj; 368 } 369 370 375 protected JavaEditor createJavaEditor () { 376 JavaEditor je = new JavaEditor (this); 377 return je; 378 } 379 380 386 protected Node createNodeDelegate () { 387 JavaNode node = new JavaNode (this); 388 return node; 389 } 390 391 395 public SourceElement getSource() { 396 if (source == null) { 398 synchronized (lock) { 399 if (source == null) 400 source = new SourceElement (new SrcElementImpl (this)); 401 } 402 } 403 return source; 404 } 405 406 410 public JavaEditor getJavaEditor() { 411 if (editorSupport == null) { 412 synchronized (this) { 413 editorSupport = createJavaEditor(); 414 if (parserGlue != null) 415 parserGlue.cloneableSupportCreated(editorSupport); 416 else 417 initializeParsingSupport(); 418 } 419 } 420 return editorSupport; 421 } 422 423 425 private static NodeFactoryPool explorerFactories; 426 private static NodeFactoryPool browserFactories; 427 private static ElementNodeFactory basicBrowser; 428 429 435 synchronized static ElementNodeFactory createBasicExplorerFactory() { 436 return JavaElementNodeFactory.DEFAULT; 437 } 438 439 445 synchronized static ElementNodeFactory createBasicBrowserFactory() { 446 if (basicBrowser == null) { 447 basicBrowser = org.netbeans.modules.java.ui.nodes.SourceNodes.createElementNodeFactory( 448 org.netbeans.modules.java.ui.nodes.SourceNodes.getBrowserFactory()); 449 } 450 return basicBrowser; 451 } 452 453 public static ElementNodeFactory getExplorerFactory() { 454 NodeFactoryPool pool = createExplorerFactory(); 455 ElementNodeFactory f = null; 456 457 if (pool != null) 458 f = pool.getHead(); 459 if (f == null) 460 f = createBasicExplorerFactory(); 461 return f; 462 } 463 464 468 public static ElementNodeFactory getBrowserFactory() { 469 ErrorManager.getDefault().notify( 470 ErrorManager.WARNING, 471 new IllegalStateException ("JavaDataObject.getBrowserFactory is deprecated. Use SourceNodes.getBrowserFactory() instead.") ); 473 return createBasicBrowserFactory(); 474 } 475 476 static NodeFactoryPool createFactoryPool(String folderName, ElementNodeFactory def) { 477 FileObject f = Repository.getDefault().getDefaultFileSystem().findResource(folderName); 478 if (f == null) 479 return null; 480 try { 481 DataFolder folder = (DataFolder)DataObject.find(f).getCookie(DataFolder.class); 482 return new NodeFactoryPool(folder, def); 483 } catch (DataObjectNotFoundException ex) { 484 return null; 485 } 486 } 487 488 synchronized static NodeFactoryPool createBrowserFactory() { 489 if (browserFactories != null) 490 return browserFactories; 491 browserFactories = createFactoryPool("/NodeFactories/java/objectbrowser", createBasicBrowserFactory()); return browserFactories; 493 } 494 495 synchronized static NodeFactoryPool createExplorerFactory() { 496 if (explorerFactories != null) 497 return explorerFactories; 498 explorerFactories = createFactoryPool("/NodeFactories/java/explorer", createBasicExplorerFactory()); return explorerFactories; 500 } 501 502 507 public static void addExplorerFilterFactory( FilterFactory factory ) { 508 NodeFactoryPool p = createExplorerFactory(); 509 if (p != null) 510 p.addFactory(factory); 511 } 512 513 518 public static void removeExplorerFilterFactory( FilterFactory factory ) { 519 NodeFactoryPool p = createExplorerFactory(); 520 if (p != null) 521 p.removeFactory(factory); 522 } 523 524 529 public static void addBrowserFilterFactory(FilterFactory factory) { 530 NodeFactoryPool p = createBrowserFactory(); 531 if (p != null) 532 p.addFactory(factory); 533 } 534 535 540 public static void removeBrowserFilterFactory( FilterFactory factory ) { 541 NodeFactoryPool p = createBrowserFactory(); 542 if (p != null) 543 p.removeFactory(factory); 544 } 545 546 547 protected static boolean isValidPackageName(String str) { 548 StringTokenizer tok = new StringTokenizer(str, "."); while (tok.hasMoreTokens()) { 550 String part = tok.nextToken(); 551 if (!org.openide.util.Utilities.isJavaIdentifier(part)) 552 return false; 553 } 554 return true; 555 } 556 557 protected void primaryFileMoved(FileObject oldFile, FileObject newFile) { 558 addSourceChangeListener(oldFile); 559 } 560 561 protected void primaryFileChanged() { 562 } 566 567 private class PrimaryListener extends FileChangeAdapter implements PropertyChangeListener { 569 public void propertyChange(final PropertyChangeEvent evt) { 570 if (!initialized) 571 return; 572 String propName = evt.getPropertyName(); 573 if (PROP_PRIMARY_FILE.equals(propName)) { 574 primaryFileMoved((FileObject)evt.getOldValue(), (FileObject)evt.getNewValue()); 575 } else if (PROP_NAME.equals(propName)) { 576 previousFileName = (String )evt.getOldValue(); 577 primaryFileMoved(getPrimaryFile(), getPrimaryFile()); 578 } 579 } 580 581 public void fileChanged(FileEvent e) { 582 if (!initialized) 583 return; 584 primaryFileChanged(); 585 } 586 } 587 588 589 595 Date getLastModified() { 596 SaveCookie c = (SaveCookie)getCookie(SaveCookie.class); 597 if (c != null) { 598 EditorCookie ck = (EditorCookie)getCookie(EditorCookie.class); 599 if (ck != null && ck.isModified()) 600 return new Date(); 601 } 602 return getPrimaryFile().lastModified(); 603 } 604 605 608 public Node.Cookie createCookie(Class klass) { 609 if (klass.isAssignableFrom(JavaEditor.class)) { 611 return getJavaEditor(); 612 } 613 if (SourceCookie.class.isAssignableFrom(klass) || 614 JavaParser.class.isAssignableFrom(klass)) { 615 if (initializeParsingSupport() == null) 616 return null; 617 if (klass.isAssignableFrom(parserGlue.getClass())) 618 return parserGlue; 619 else 620 return parserGlue.getParser(); 621 } 622 return null; 623 } 624 625 626 630 public Collection getCompiledClasses() { 631 Thread.dumpStack(); 632 return Collections.EMPTY_LIST; 633 } 634 635 640 } 641 | Popular Tags |