1 19 20 package org.netbeans.modules.web.project.ui; 21 22 import java.awt.Image ; 23 import java.awt.event.ActionEvent ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyChangeListener ; 26 import java.io.CharConversionException ; 27 import java.io.IOException ; 28 import java.util.ArrayList ; 29 import java.util.Arrays ; 30 import java.util.Collection ; 31 import java.util.Enumeration ; 32 import java.util.HashMap ; 33 import java.util.HashSet ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.ResourceBundle ; 37 import java.util.Set ; 38 import java.util.StringTokenizer ; 39 import javax.swing.AbstractAction ; 40 import javax.swing.Action ; 41 import javax.swing.JSeparator ; 42 import javax.swing.event.ChangeEvent ; 43 import javax.swing.event.ChangeListener ; 44 import org.openide.ErrorManager; 45 import org.openide.actions.ToolsAction; 46 import org.openide.filesystems.FileObject; 47 import org.openide.filesystems.FileSystem; 48 import org.openide.filesystems.FileStateInvalidException; 49 import org.openide.filesystems.FileStatusEvent; 50 import org.openide.filesystems.FileStatusListener; 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.FolderLookup; 57 import org.openide.nodes.*; 58 import org.openide.util.ContextAwareAction; 59 import org.openide.util.HelpCtx; 60 import org.openide.util.Lookup; 61 import org.openide.util.NbBundle; 62 import org.openide.util.RequestProcessor; 63 import org.openide.util.Utilities; 64 import org.openide.util.WeakListeners; 65 import org.openide.util.actions.SystemAction; 66 import org.openide.util.lookup.Lookups; 67 import org.openide.xml.XMLUtil; 68 import org.netbeans.api.java.platform.JavaPlatformManager; 69 import org.netbeans.api.project.Project; 70 import org.netbeans.api.project.ProjectUtils; 71 import org.netbeans.spi.project.ActionProvider; 72 import org.netbeans.api.java.project.JavaProjectConstants; 73 import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport; 74 import org.netbeans.spi.java.project.support.ui.PackageView; 75 import org.netbeans.api.project.FileOwnerQuery; 76 import org.netbeans.api.project.SourceGroup; 77 import org.netbeans.api.project.Sources; 78 import org.netbeans.spi.project.support.ant.AntProjectHelper; 79 import org.netbeans.spi.project.support.ant.PropertyEvaluator; 80 import org.netbeans.spi.project.support.ant.ReferenceHelper; 81 import org.netbeans.spi.project.ui.LogicalViewProvider; 82 import org.netbeans.spi.project.ui.support.CommonProjectActions; 83 import org.netbeans.spi.project.ui.support.DefaultProjectOperations; 84 import org.netbeans.spi.project.ui.support.ProjectSensitiveActions; 85 import org.netbeans.modules.j2ee.common.ui.BrokenServerSupport; 86 import org.netbeans.modules.j2ee.deployment.devmodules.api.J2eeModule; 87 import org.netbeans.modules.j2ee.deployment.devmodules.spi.InstanceListener; 88 import org.netbeans.modules.j2ee.deployment.devmodules.spi.J2eeModuleProvider; 89 import org.netbeans.modules.web.api.webmodule.WebProjectConstants; 90 import org.netbeans.modules.web.project.SourceRoots; 91 import org.netbeans.modules.web.project.UpdateHelper; 92 import org.netbeans.modules.web.project.WebProject; 93 import org.netbeans.modules.web.project.ui.customizer.WebProjectProperties; 94 import org.netbeans.spi.project.ui.support.NodeFactorySupport; 95 96 100 public class WebLogicalViewProvider implements LogicalViewProvider { 101 102 private static final RequestProcessor BROKEN_LINKS_RP = new RequestProcessor("WebLogicalViewProvider.BROKEN_LINKS_RP"); 104 private final WebProject project; 105 private final UpdateHelper helper; 106 private final PropertyEvaluator evaluator; 107 private final ReferenceHelper resolver; 108 private List <ChangeListener > changeListeners; 109 110 public WebLogicalViewProvider(WebProject project, UpdateHelper helper, PropertyEvaluator evaluator, ReferenceHelper resolver) { 111 this.project = project; 112 assert project != null; 113 this.helper = helper; 114 assert helper != null; 115 this.evaluator = evaluator; 116 assert evaluator != null; 117 this.resolver = resolver; 118 } 119 120 public Node createLogicalView() { 121 return new WebLogicalViewRootNode(); 122 } 123 124 public PropertyEvaluator getEvaluator() { 125 return evaluator; 126 } 127 128 public ReferenceHelper getRefHelper() { 129 return resolver; 130 } 131 132 public UpdateHelper getUpdateHelper() { 133 return helper; 134 } 135 136 public Node findPath(Node root, Object target) { 137 Project project = root.getLookup().lookup(Project.class); 138 if (project == null) 139 return null; 140 141 if (target instanceof FileObject) { 142 FileObject fo = (FileObject) target; 143 Project owner = FileOwnerQuery.getOwner(fo); 144 if (!project.equals(owner)) 145 return null; 147 for (Node n : root.getChildren().getNodes(true)) { 149 Node result = PackageView.findPath(n, target); 150 if (result != null) 151 return result; 152 } 153 154 Node result = findNodeInConfigFiles(root, fo); 156 if (result != null) 157 return result; 158 159 result = findNodeInDocBase(root, fo); 161 if (result != null) 162 return result; 163 164 } 165 return null; 166 } 167 168 private Node findNodeInDocBase(Node root, FileObject fo) { 169 FileObject rootfo = helper.getAntProjectHelper().resolveFileObject(evaluator.getProperty (WebProjectProperties.WEB_DOCBASE_DIR)); 170 String relPath = FileUtil.getRelativePath(rootfo, fo); 171 if (relPath == null) { 172 return null; 173 } 174 int idx = relPath.lastIndexOf('.'); if (idx != -1) 176 relPath = relPath.substring(0, idx); 177 StringTokenizer st = new StringTokenizer (relPath, "/"); Node result = NodeOp.findChild(root,rootfo.getName()); 179 while (st.hasMoreTokens()) { 180 result = NodeOp.findChild(result, st.nextToken()); 181 } 182 183 return result; 184 } 185 186 private Node findNodeInConfigFiles(Node root, FileObject fo) { 187 String nodeName; 190 try { 191 DataObject dobj = DataObject.find(fo); 192 nodeName = dobj.getName(); 193 } catch (DataObjectNotFoundException e) { 194 nodeName = fo.getName(); 195 } 196 Node configFiles = root.getChildren().findChild("configurationFiles"); if (configFiles == null) { 198 return null; 199 } 200 return NodeOp.findChild(configFiles, nodeName); 201 } 202 203 public synchronized void addChangeListener (ChangeListener l) { 204 if (this.changeListeners == null) { 205 this.changeListeners = new ArrayList <ChangeListener >(); 206 } 207 this.changeListeners.add (l); 208 } 209 210 public synchronized void removeChangeListener (ChangeListener l) { 211 if (this.changeListeners == null) { 212 return; 213 } 214 this.changeListeners.remove (l); 215 } 216 217 222 public void testBroken () { 223 ChangeListener [] _listeners; 224 synchronized (this) { 225 if (this.changeListeners == null) { 226 return; 227 } 228 _listeners = changeListeners.toArray(new ChangeListener [changeListeners.size()]); 229 230 } 231 ChangeEvent event = new ChangeEvent (this); 232 for (ChangeListener l : _listeners) { 233 l.stateChanged(event); 234 } 235 } 236 237 239 private static final String [] BREAKABLE_PROPERTIES = new String [] { 240 WebProjectProperties.JAVAC_CLASSPATH, 241 WebProjectProperties.DEBUG_CLASSPATH, 242 WebProjectProperties.RUN_TEST_CLASSPATH, 243 WebProjectProperties.DEBUG_TEST_CLASSPATH, 244 WebProjectProperties.JAVAC_TEST_CLASSPATH, 245 WebProjectProperties.WAR_CONTENT_ADDITIONAL, 246 WebProjectProperties.WEB_DOCBASE_DIR 247 }; 248 249 public boolean hasBrokenLinks() { 250 return BrokenReferencesSupport.isBroken(helper.getAntProjectHelper(), resolver, getBreakableProperties(), 251 new String [] {WebProjectProperties.JAVA_PLATFORM}); 252 } 253 254 private String [] getBreakableProperties() { 255 SourceRoots roots = this.project.getSourceRoots(); 256 String [] srcRootProps = roots.getRootProperties(); 257 roots = this.project.getTestSourceRoots(); 258 String [] testRootProps = roots.getRootProperties(); 259 String [] result = new String [BREAKABLE_PROPERTIES.length + srcRootProps.length + testRootProps.length]; 260 System.arraycopy(BREAKABLE_PROPERTIES, 0, result, 0, BREAKABLE_PROPERTIES.length); 261 System.arraycopy(srcRootProps, 0, result, BREAKABLE_PROPERTIES.length, srcRootProps.length); 262 System.arraycopy(testRootProps, 0, result, BREAKABLE_PROPERTIES.length + srcRootProps.length, testRootProps.length); 263 return result; 264 } 265 266 private static Image brokenProjectBadge = Utilities.loadImage( "org/netbeans/modules/web/project/ui/resources/brokenProjectBadge.gif" ); 268 270 private final class WebLogicalViewRootNode extends AbstractNode implements Runnable , FileStatusListener, ChangeListener , PropertyChangeListener { 271 272 private final Action brokenLinksAction; 273 private final BrokenServerAction brokenServerAction; 274 private boolean broken; 275 276 private Set <FileObject> files; 278 private Map <FileSystem,FileStatusListener> fileSystemListeners; 279 private RequestProcessor.Task task; 280 private final Object privateLock = new Object (); 281 private boolean iconChange; 282 private boolean nameChange; 283 private ChangeListener sourcesListener; 284 private Map <SourceGroup,PropertyChangeListener > groupsListeners; 285 287 288 public WebLogicalViewRootNode() { 289 super(NodeFactorySupport.createCompositeChildren(project, "Projects/org-netbeans-modules-web-project/Nodes"), 291 Lookups.singleton(project)); 292 setIconBaseWithExtension("org/netbeans/modules/web/project/ui/resources/webProjectIcon.gif"); super.setName( ProjectUtils.getInformation( project ).getDisplayName() ); 294 if (hasBrokenLinks()) { 295 broken = true; 296 } 297 brokenLinksAction = new BrokenLinksAction(); 298 brokenServerAction = new BrokenServerAction(); 299 J2eeModuleProvider moduleProvider = (J2eeModuleProvider)project.getLookup().lookup(J2eeModuleProvider.class); 300 moduleProvider.addInstanceListener((InstanceListener)WeakListeners.create( 301 InstanceListener.class, brokenServerAction, moduleProvider)); 302 setProjectFiles(project); 303 } 304 305 protected void setProjectFiles(Project project) { 306 Sources sources = ProjectUtils.getSources(project); if (sourcesListener == null) { 308 sourcesListener = WeakListeners.change(this, sources); 309 sources.addChangeListener(sourcesListener); 310 } 311 setGroups(Arrays.asList(sources.getSourceGroups(Sources.TYPE_GENERIC))); 312 } 313 314 315 private void setGroups(Collection <SourceGroup> groups) { 316 if (groupsListeners != null) { 317 for (Map.Entry <SourceGroup,PropertyChangeListener > e : groupsListeners.entrySet()) { 318 e.getKey().removePropertyChangeListener(e.getValue()); 319 } 320 } 321 groupsListeners = new HashMap <SourceGroup,PropertyChangeListener >(); 322 Set <FileObject> roots = new HashSet <FileObject>(); 323 for (SourceGroup group : groups) { 324 PropertyChangeListener pcl = WeakListeners.propertyChange(this, group); 325 groupsListeners.put(group, pcl); 326 group.addPropertyChangeListener(pcl); 327 FileObject fo = group.getRootFolder(); 328 if (project.getProjectDirectory().equals(fo)) { 329 Enumeration en = project.getProjectDirectory().getChildren(false); 332 while (en.hasMoreElements()) { 333 FileObject child = (FileObject) en.nextElement(); 334 if (FileOwnerQuery.getOwner(child) == project) { 335 roots.add(child); 336 } 337 } 338 } else { 339 roots.add(fo); 340 } 341 } 342 setFiles(roots); 343 } 344 345 protected void setFiles(Set <FileObject> files) { 346 if (fileSystemListeners != null) { 347 for (Map.Entry <FileSystem,FileStatusListener> e : fileSystemListeners.entrySet()) { 348 e.getKey().removeFileStatusListener(e.getValue()); 349 } 350 } 351 352 fileSystemListeners = new HashMap <FileSystem,FileStatusListener>(); 353 this.files = files; 354 if (files == null) 355 return; 356 357 Set <FileSystem> hookedFileSystems = new HashSet <FileSystem>(); 358 for (FileObject fo : files) { 359 try { 360 FileSystem fs = fo.getFileSystem(); 361 if (hookedFileSystems.contains(fs)) { 362 continue; 363 } 364 hookedFileSystems.add(fs); 365 FileStatusListener fsl = FileUtil.weakFileStatusListener(this, fs); 366 fs.addFileStatusListener(fsl); 367 fileSystemListeners.put(fs, fsl); 368 } catch (FileStateInvalidException e) { 369 ErrorManager err = ErrorManager.getDefault(); 370 err.annotate(e, ErrorManager.UNKNOWN, "Cannot get " + fo + " filesystem, ignoring...", null, null, null); err.notify(ErrorManager.INFORMATIONAL, e); 372 } 373 } 374 } 375 376 public Image getIcon (int type) { 377 Image img = getMyIcon (type); 378 379 if (files != null && !files.isEmpty()) { 380 try { 381 FileObject fo = files.iterator().next(); 382 img = fo.getFileSystem().getStatus().annotateIcon(img, type, files); 383 } catch (FileStateInvalidException e) { 384 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 385 } 386 } 387 388 return img; 389 } 390 391 public Image getOpenedIcon (int type) { 392 Image img = getMyOpenedIcon(type); 393 394 if (files != null && !files.isEmpty()) { 395 try { 396 FileObject fo = files.iterator().next(); 397 img = fo.getFileSystem().getStatus().annotateIcon(img, type, files); 398 } catch (FileStateInvalidException e) { 399 ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, e); 400 } 401 } 402 403 return img; 404 } 405 406 public void run() { 407 boolean fireIcon; 408 boolean fireName; 409 synchronized (privateLock) { 410 fireIcon = iconChange; 411 fireName = nameChange; 412 iconChange = false; 413 nameChange = false; 414 } 415 if (fireIcon) { 416 fireIconChange(); 417 fireOpenedIconChange(); 418 } 419 if (fireName) { 420 fireDisplayNameChange(null, null); 421 } 422 } 423 424 public void annotationChanged(FileStatusEvent event) { 425 if (task == null) { 426 task = RequestProcessor.getDefault().create(this); 427 } 428 429 synchronized (privateLock) { 430 if ((!iconChange && event.isIconChange()) || (!nameChange && event.isNameChange())) { 431 for (FileObject fo : files) { 432 if (event.hasChanged(fo)) { 433 iconChange |= event.isIconChange(); 434 nameChange |= event.isNameChange(); 435 } 436 } 437 } 438 } 439 440 task.schedule(50); } 442 443 public void stateChanged(ChangeEvent e) { 445 setProjectFiles(project); 446 } 447 448 public void propertyChange(PropertyChangeEvent evt) { 450 setProjectFiles(project); 451 } 452 453 public Image getMyIcon( int type ) { 454 Image original = super.getIcon( type ); 455 return broken || brokenServerAction.isEnabled() ? Utilities.mergeImages(original, brokenProjectBadge, 8, 0) : original; 456 } 457 458 public Image getMyOpenedIcon( int type ) { 459 Image original = super.getOpenedIcon(type); 460 return broken || brokenServerAction.isEnabled() ? Utilities.mergeImages(original, brokenProjectBadge, 8, 0) : original; 461 } 462 463 public String getHtmlDisplayName() { 464 String dispName = super.getDisplayName(); 465 try { 466 dispName = XMLUtil.toElementContent(dispName); 467 } catch (CharConversionException ex) { 468 return dispName; 469 } 470 return broken || brokenServerAction.isEnabled() ? "<font color=\"#A40000\">" + dispName + "</font>" : null; } 472 473 public Action [] getActions( boolean context ) { 474 return getAdditionalActions(); 475 } 476 477 public boolean canRename() { 478 return true; 479 } 480 481 public void setName(String s) { 482 DefaultProjectOperations.performDefaultRenameOperation(project, s); 483 } 484 485 public HelpCtx getHelpCtx() { 486 return new HelpCtx(WebLogicalViewRootNode.class); 487 } 488 489 491 private Action [] getAdditionalActions() { 492 493 ResourceBundle bundle = NbBundle.getBundle(WebLogicalViewProvider.class); 494 495 J2eeModuleProvider provider = (J2eeModuleProvider) project.getLookup().lookup(J2eeModuleProvider.class); 496 List <Action > actions = new ArrayList <Action >(); 497 actions.add(CommonProjectActions.newFileAction()); 498 actions.add(null); 499 actions.add(ProjectSensitiveActions.projectCommandAction( ActionProvider.COMMAND_BUILD, bundle.getString( "LBL_BuildAction_Name" ), null )); actions.add(ProjectSensitiveActions.projectCommandAction( ActionProvider.COMMAND_REBUILD, bundle.getString( "LBL_RebuildAction_Name" ), null )); actions.add(ProjectSensitiveActions.projectCommandAction( ActionProvider.COMMAND_CLEAN, bundle.getString( "LBL_CleanAction_Name" ), null )); if (provider != null && provider.hasVerifierSupport()) { 503 actions.add(ProjectSensitiveActions.projectCommandAction( "verify", bundle.getString( "LBL_VerifyAction_Name" ), null )); } 505 actions.add(ProjectSensitiveActions.projectCommandAction( JavaProjectConstants.COMMAND_JAVADOC, bundle.getString( "LBL_JavadocAction_Name" ), null )); actions.add(null); 507 actions.add(ProjectSensitiveActions.projectCommandAction( ActionProvider.COMMAND_RUN, bundle.getString( "LBL_RunAction_Name" ), null )); actions.add(ProjectSensitiveActions.projectCommandAction( ActionProvider.COMMAND_DEBUG, bundle.getString( "LBL_DebugAction_Name" ), null )); actions.add(ProjectSensitiveActions.projectCommandAction( WebProjectConstants.COMMAND_REDEPLOY, bundle.getString( "LBL_RedeployAction_Name" ), null )); actions.add(null); 511 actions.add(CommonProjectActions.setAsMainProjectAction()); 512 actions.add(CommonProjectActions.openSubprojectsAction()); 513 actions.add(CommonProjectActions.closeProjectAction()); 514 actions.add(null); 515 actions.add(CommonProjectActions.renameProjectAction()); 516 actions.add(CommonProjectActions.moveProjectAction()); 517 actions.add(CommonProjectActions.copyProjectAction()); 518 actions.add(CommonProjectActions.deleteProjectAction()); 519 actions.add(null); 520 actions.add(SystemAction.get( org.openide.actions.FindAction.class )); 521 522 524 FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource("Projects/Actions"); if (fo != null) { 526 for (Object next : new FolderLookup(DataFolder.findFolder(fo)).getLookup().lookupAll(Object .class)) { 527 if (next instanceof Action ) { 528 actions.add((Action ) next); 529 } else if (next instanceof JSeparator ) { 530 actions.add(null); 531 } 532 } 533 } 534 535 actions.add(null); 536 actions.add(SystemAction.get(ToolsAction.class)); 537 actions.add(null); 538 539 if (brokenLinksAction != null && brokenLinksAction.isEnabled()) { 540 actions.add(brokenLinksAction); 541 } 542 if (brokenServerAction.isEnabled()) { 543 actions.add(brokenServerAction); 544 } 545 actions.add(CommonProjectActions.customizeProjectAction()); 546 547 return actions.toArray(new Action [actions.size()]); 548 } 549 550 553 private class BrokenLinksAction extends AbstractAction implements PropertyChangeListener , ChangeListener , Runnable { 554 555 private RequestProcessor.Task task = null; 556 557 private final PropertyChangeListener weakPCL; 558 559 public BrokenLinksAction() { 560 putValue(Action.NAME,NbBundle.getMessage(WebLogicalViewProvider.class, "LBL_Fix_Broken_Links_Action")); 561 setEnabled(broken); 562 evaluator.addPropertyChangeListener( this ); 563 weakPCL = WeakListeners.propertyChange( this, JavaPlatformManager.getDefault() ); 567 JavaPlatformManager.getDefault().addPropertyChangeListener( weakPCL ); 568 WebLogicalViewProvider.this.addChangeListener ((ChangeListener )WeakListeners.change(this,WebLogicalViewProvider.this)); 569 } 570 571 public void actionPerformed(ActionEvent e) { 572 try { 573 helper.requestSave(); 574 BrokenReferencesSupport.showCustomizer(helper.getAntProjectHelper(), resolver, getBreakableProperties(), new String []{WebProjectProperties.JAVA_PLATFORM}); 575 run(); 576 } catch (IOException ioe) { 577 ErrorManager.getDefault().notify (ioe); 578 } 579 } 580 581 public void propertyChange(PropertyChangeEvent evt) { 582 refsMayChanged(); 583 } 584 585 public void stateChanged (ChangeEvent evt) { 586 refsMayChanged (); 587 } 588 589 public synchronized void run() { 590 boolean old = WebLogicalViewRootNode.this.broken; 591 broken = hasBrokenLinks(); 592 if (old != broken) { 593 setEnabled(broken); 594 fireIconChange(); 595 fireOpenedIconChange(); 596 fireDisplayNameChange(null, null); 597 project.getWebProjectProperties().save(); 598 } 599 } 600 601 public void refsMayChanged() { 602 if (task == null) { 606 task = BROKEN_LINKS_RP.create(this); 607 } 608 task.schedule(100); 609 } 610 611 } 612 613 private class BrokenServerAction extends AbstractAction implements 614 InstanceListener, PropertyChangeListener { 615 616 private boolean brokenServer; 617 618 public BrokenServerAction() { 619 putValue(Action.NAME,NbBundle.getMessage(WebLogicalViewProvider.class, "LBL_Fix_Missing_Server_Action")); evaluator.addPropertyChangeListener(this); 621 checkMissingServer(); 622 } 623 624 public boolean isEnabled() { 625 return brokenServer; 626 } 627 628 public void actionPerformed(ActionEvent e) { 629 String j2eeSpec = helper.getProperties(AntProjectHelper.PROJECT_PROPERTIES_PATH). 630 getProperty(WebProjectProperties.J2EE_PLATFORM); 631 String instance = BrokenServerSupport.selectServer(j2eeSpec, J2eeModule.WAR); 632 if (instance != null) { 633 WebProjectProperties.setServerInstance( 634 project, helper, instance); 635 } 636 checkMissingServer(); 637 } 638 639 public void propertyChange(PropertyChangeEvent evt) { 640 if (WebProjectProperties.J2EE_SERVER_INSTANCE.equals(evt.getPropertyName())) { 641 checkMissingServer(); 642 } 643 } 644 645 public void changeDefaultInstance(String oldServerInstanceID, String newServerInstanceID) { 646 } 647 648 public void instanceAdded(String serverInstanceID) { 649 checkMissingServer(); 650 } 651 652 public void instanceRemoved(String serverInstanceID) { 653 checkMissingServer(); 654 } 655 656 private void checkMissingServer() { 657 boolean old = brokenServer; 658 String servInstID = evaluator.getProperty(WebProjectProperties.J2EE_SERVER_INSTANCE); 659 brokenServer = BrokenServerSupport.isBroken(servInstID); 660 if (old != brokenServer) { 661 fireIconChange(); 662 fireOpenedIconChange(); 663 fireDisplayNameChange(null, null); 664 } 665 } 666 } 667 } 668 669 672 public static class Actions { 673 674 private Actions() {} 676 public static Action createAction( String key, String name, boolean global ) { 677 return new ActionImpl( key, name, global ? Utilities.actionsGlobalContext() : null ); 678 } 679 680 private static class ActionImpl extends AbstractAction implements ContextAwareAction { 681 682 Lookup context; 683 String name; 684 String command; 685 686 public ActionImpl( String command, String name, Lookup context ) { 687 super( name ); 688 this.context = context; 689 this.command = command; 690 this.name = name; 691 } 692 693 public void actionPerformed( ActionEvent e ) { 694 695 Project project = (Project)context.lookup( Project.class ); 696 ActionProvider ap = (ActionProvider)project.getLookup().lookup( ActionProvider.class); 697 698 ap.invokeAction( command, context ); 699 700 } 701 702 public Action createContextAwareInstance( Lookup lookup ) { 703 return new ActionImpl( command, name, lookup ); 704 } 705 } 706 707 } 708 709 } 710 | Popular Tags |