This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 58866
Collapse All | Expand All

(-)projectapi/apichanges.xml (+26 lines)
Lines 76-81 Link Here
76
76
77
    <changes>
77
    <changes>
78
78
79
        <change id="delete-support">
80
            <api name="general"/>
81
            <summary>Support for project delete</summary>
82
            <version major="1" minor="6"/>
83
            <date day="20" month="6" year="2005"/>
84
            <author login="jlahoda"/>
85
            <compatibility>
86
                <p>
87
                    As only the ProjectManager is allowed to implement ProjectState interface,
88
                    this change should not directly affect any clients.
89
                </p>
90
            </compatibility>
91
            <description>
92
                <p>
93
                    The <code>notifyDeleted</code> action is added to the <code>ProjectState</code>,
94
                    allowing the project implmentation to let the <code>ProjectManager</code>
95
                    know that the project has been deleted.
96
                </p>
97
                <p>
98
                    <code>ProjectOperations</code> and <code>ProjectOperationsImplementation</code> added to support
99
                    project delete operation.
100
                </p>
101
            </description>
102
            <issue number="51468"/>
103
        </change>
104
        
79
        <change id="markExternal-for-file-and-URIs">
105
        <change id="markExternal-for-file-and-URIs">
80
            <api name="general"/>
106
            <api name="general"/>
81
            <summary>The FileOwnerQuery.markExternalOwner allows registration of individal files and URIs</summary>
107
            <summary>The FileOwnerQuery.markExternalOwner allows registration of individal files and URIs</summary>
(-)projectapi/src/org/netbeans/api/project/ProjectManager.java (-1 / +33 lines)
Lines 15-20 Link Here
15
15
16
import java.io.IOException;
16
import java.io.IOException;
17
import java.lang.ref.Reference;
17
import java.lang.ref.Reference;
18
import java.net.URI;
18
import java.util.Arrays;
19
import java.util.Arrays;
19
import java.util.HashSet;
20
import java.util.HashSet;
20
import java.util.Iterator;
21
import java.util.Iterator;
Lines 455-461 Link Here
455
                }
456
                }
456
            });
457
            });
457
        }
458
        }
458
        
459
460
        public void notifyDeleted() throws IllegalStateException {
461
            assert p != null;
462
            mutex().writeAccess(new Mutex.Action() {
463
                public Object run() {
464
                    if (proj2Factory.get(p) == null) {
465
                        throw new IllegalStateException("An attempt to call notifyDeleted more than once. Project: " + p.getProjectDirectory());
466
                    }
467
                    
468
                    dir2Proj.remove(p.getProjectDirectory());
469
                    proj2Factory.remove(p);
470
                    modifiedProjects.remove(p);
471
                    return null;
472
                }
473
            });
474
        }
475
459
    }
476
    }
460
    
477
    
461
    /**
478
    /**
Lines 548-553 Link Here
548
        } catch (MutexException e) {
565
        } catch (MutexException e) {
549
            throw (IOException)e.getException();
566
            throw (IOException)e.getException();
550
        }
567
        }
568
    }
569
    
570
    /**
571
     * Check whether a given project is still valid (ie. not deleted).
572
     * <p>Acquires read access.</p>
573
     * @param p a project loaded by this manager
574
     */
575
    public boolean isValid(final Project p) {
576
        return ((Boolean)mutex().readAccess(new Mutex.Action() {
577
            public Object run() {
578
                synchronized (dir2Proj) {
579
                    return Boolean.valueOf(proj2Factory.containsKey(p));
580
                }
581
            }
582
        })).booleanValue();
551
    }
583
    }
552
    
584
    
553
    /**
585
    /**
(-)projectapi/src/org/netbeans/api/project/ProjectOperations.java (+134 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 *
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.api.project;
15
16
import java.io.IOException;
17
import java.util.ArrayList;
18
import java.util.Collection;
19
import java.util.Iterator;
20
import java.util.List;
21
import org.netbeans.spi.project.ProjectOperationsImplementation.DataFilesProviderImplementation;
22
import org.netbeans.spi.project.ProjectOperationsImplementation.DeleteOperationImplementation;
23
import org.openide.util.Lookup;
24
25
/**Allows gathering information for vaious project operations (currently only project delete, but will
26
 * be extended in the future).
27
 *
28
 * <p><b><font size=+1>Project Delete Operation</font></b>
29
 *
30
 * Consists of {@link #getMetadataFiles(Project) getMetadataFiles},
31
 * {@link #getDataFiles(Project) getDataFiles}, {@link #performClean(Project) performClean}
32
 * and {@link #notifyDeleted(Project) notifyDeleted}.
33
 *
34
 * The delete operation should run in two phases: preparation, when
35
 * {@link #getMetadataFiles(Project) getMetadataFiles} and {@link #getDataFiles(Project) getDataFiles}
36
 * (any number of times,
37
 * in any order) are called and performing, when {@link #performClean(Project) performClean} should be called,
38
 * then the files previously returned should be deleted (as required by the user)
39
 * and finally {@link #notifyDeleted(Project) notifyDeleted} should be called.
40
 *
41
 * @since  1.6
42
 * @author Jan Lahoda
43
 */
44
public final class ProjectOperations {
45
    
46
    private static ProjectOperations INSTANCE = null;
47
    
48
    public static synchronized ProjectOperations getDefault() {
49
        if (INSTANCE == null) {
50
            INSTANCE = new ProjectOperations();
51
        }
52
        
53
        return INSTANCE;
54
    }
55
    
56
    private ProjectOperations() {
57
    }
58
    
59
    /**Return list of files that are considered metadata files and folders for the given project.
60
     * Returns meaningfull values only if some of the <code>is*Supported</code> methods
61
     * return <code>true</code>.
62
     *
63
     * @param prj project to test
64
     * @return list of metadata files/folders
65
     */
66
    public List/*<FileObject>*/ getMetadataFiles(Project prj) {
67
        List/*<FileObject>*/ result = new ArrayList();
68
        
69
        for (Iterator i = getProjectsOperationsImplementation(prj).iterator(); i.hasNext(); ) {
70
            result.addAll(((DataFilesProviderImplementation) i.next()).getMetadataFiles());
71
        }
72
        
73
        return result;
74
    }
75
            
76
    /**Return list of files that are considered source files and folders for the given project.
77
     * Returns meaningfull values only if some of the <code>is*Supported</code> methods
78
     * return <code>true</code>.
79
     *
80
     * @param prj project to test
81
     * @return list of data files/folders
82
     */
83
    public List/*<FileObject>*/ getDataFiles(Project prj) {
84
        List/*<FileObject>*/ result = new ArrayList();
85
        
86
        for (Iterator i = getProjectsOperationsImplementation(prj).iterator(); i.hasNext(); ) {
87
            result.addAll(((DataFilesProviderImplementation) i.next()).getDataFiles());
88
        }
89
        
90
        return result;
91
    }
92
    
93
    /**Test whether the delete operation is supported on the given project.
94
     *
95
     * 
96
     * @param prj project to test
97
     * @return <code>true</code> if the project supports delete operation,
98
     *         <code>false</code> otherwise
99
     */
100
    public boolean isDeleteOperationSupported(Project prj) {
101
        return !getDeleteOperationImplementation(prj).isEmpty();
102
    }
103
    
104
    /**Performs pre-delete clean of the project. Should be called immediatelly before
105
     * the project is deleted.
106
     *
107
     * @param prj project to clean
108
     */
109
    public void performClean(Project prj) throws IOException {
110
        for (Iterator i = getDeleteOperationImplementation(prj).iterator(); i.hasNext(); ) {
111
            ((DeleteOperationImplementation) i.next()).performClean();
112
        }
113
    }
114
    
115
    /**Post-delete notification that the project has been deleted.. Should be called immediatelly after
116
     * the project is deleted.
117
     *
118
     * @param prj deleted project
119
     */
120
    public void notifyDeleted(Project prj) throws IOException {
121
        for (Iterator i = getDeleteOperationImplementation(prj).iterator(); i.hasNext(); ) {
122
            ((DeleteOperationImplementation) i.next()).notifyDeleted();
123
        }
124
    }
125
    
126
    private Collection/*<DeleteOperationImplementation>*/ getDeleteOperationImplementation(Project prj) {
127
        return prj.getLookup().lookup(new Lookup.Template(DeleteOperationImplementation.class)).allInstances();
128
    }
129
    
130
    private Collection/*<DataFilesProviderImplementation>*/ getProjectsOperationsImplementation(Project prj) {
131
        return prj.getLookup().lookup(new Lookup.Template(DataFilesProviderImplementation.class)).allInstances();
132
    }
133
    
134
}
(-)projectapi/src/org/netbeans/spi/project/ActionProvider.java (-1 / +7 lines)
Lines 86-92 Link Here
86
     */
86
     */
87
    String COMMAND_DEBUG_STEP_INTO = "debug.stepinto"; // NOI18N
87
    String COMMAND_DEBUG_STEP_INTO = "debug.stepinto"; // NOI18N
88
    
88
    
89
        
89
    /**
90
     * Standard command for deleting the project.
91
     *
92
     * @since 1.6
93
     */
94
    String COMMAND_DELETE = "delete"; // NOI18N
95
    
90
    /**
96
    /**
91
     * Get a list of all commands which this project supports.
97
     * Get a list of all commands which this project supports.
92
     * @return a list of command names suitable for {@link #invokeAction}
98
     * @return a list of command names suitable for {@link #invokeAction}
(-)projectapi/src/org/netbeans/spi/project/ProjectOperationsImplementation.java (+84 lines)
Added Link Here
1
/*
2
 *                 Sun Public License Notice
3
 *
4
 * The contents of this file are subject to the Sun Public License
5
 * Version 1.0 (the "License"). You may not use this file except in
6
 * compliance with the License. A copy of the License is available at
7
 * http://www.sun.com/
8
 *
9
 * The Original Code is NetBeans. The Initial Developer of the Original
10
 * Code is Sun Microsystems, Inc. Portions Copyright 1997-2005 Sun
11
 * Microsystems, Inc. All Rights Reserved.
12
 */
13
14
package org.netbeans.spi.project;
15
16
import java.io.IOException;
17
import java.util.List;
18
import org.netbeans.api.project.ProjectOperations;
19
20
/**This is only a scope class that holds several project operation interfaces.
21
 * See particular interface for more information:
22
 * <li>
23
 *     <ul>{@link DeleteOperationImplementation DeleteOperationImplementation}</ul>
24
 * </li>
25
 *
26
 * @since 1.6
27
 * @author Jan Lahoda
28
 */
29
public final class ProjectOperationsImplementation {
30
    
31
    /**
32
     * Base for various Project Operations, allows to gather metadata and data files
33
     * for a project.
34
     */
35
    public interface DataFilesProviderImplementation {
36
        
37
        /**
38
         * Returns list of {@link FileObject}s the are considered to be metadata files
39
         * and folders belonging into this project.
40
         * See {@link ProjectOperations#getMetadataFiles()} for more information.
41
         *
42
         * @return list of {@link FileObject}s that are considered metadata files and folders.
43
         */
44
        public List/*<FileObject>*/ getMetadataFiles();
45
        
46
        /**
47
         * Returns list of {@link FileObject}s the are considered to be data files and folders
48
         * belonging into this project.
49
         * See {@link ProjectOperations#getDataFiles()} for more information.
50
         *
51
         * @return list of {@link FileObject}s that are considered data files and folders.
52
         */
53
        public List/*<FileObject>*/ getDataFiles();
54
        
55
    }
56
    
57
    /**
58
     * Project Delete Operation. Allows to gather information necessary for project
59
     * delete and also provides callbacks to the project type to handle special
60
     * checkpoints during the delete.
61
     * 
62
     * An implementation of this interface should be registered in the project to support
63
     * delete operation.
64
     */
65
    public interface DeleteOperationImplementation extends DataFilesProviderImplementation {
66
        
67
        /**Pre-delete clean. The exact meaning is left on the project implementors, but
68
         * typically this means to undeloy the application and remove all artifacts
69
         * created by the build project.
70
         *
71
         * @throws IOException if an I/O operation fails.
72
         */
73
        public void performClean() throws IOException;
74
        
75
        /**Notification that the delete operation has finished. Is supposed to perform
76
         * final cleanup and to call {@link ProjectState#notifyDeleted}.
77
         *
78
         * @throws IOException if an I/O operation fails.
79
         */
80
        public void notifyDeleted() throws IOException;
81
        
82
    }
83
    
84
}
(-)projectapi/src/org/netbeans/spi/project/ProjectState.java (-2 / +19 lines)
Lines 19-26 Link Here
19
/**
19
/**
20
 * Callback permitting {@link Project}s to inform the {@link ProjectManager}
20
 * Callback permitting {@link Project}s to inform the {@link ProjectManager}
21
 * of important lifecycle events.
21
 * of important lifecycle events.
22
 * Currently the only available event is modification of the project metadata.
22
 * Currently the only available events are modification of the project metadata
23
 * However in the future other events may be added, such as moving or deleting
23
 * and project deletion notification.
24
 * However in the future other events may be added, such as moving
24
 * the project, which the project manager would need to be informed of.
25
 * the project, which the project manager would need to be informed of.
25
 * <p>
26
 * <p>
26
 * This interface may only be implemented by the project manager. A
27
 * This interface may only be implemented by the project manager. A
Lines 38-42 Link Here
38
     * <p>Acquires write access.
39
     * <p>Acquires write access.
39
     */
40
     */
40
    void markModified();
41
    void markModified();
42
    
43
    /**
44
     * <p>Inform the manager that the project has been deleted. The project will
45
     * be removed from any {@link ProjectManager}'s  mappings.
46
     * If {@link ProjectManager#findProject} is called on the project directory,
47
     * the {@link ProjectFactory ProjectFactories} are asked again to recognize
48
     * the project.</p>
49
     *
50
     * <p>The project is no longer recognized as created by the {@link ProjectManager}.</p>
51
     *
52
     * <p>Acquires write access.</p>
53
     *
54
     * @throws IllegalStateException if notifyDeleted is called more than once for a project.
55
     * @since 1.4
56
     */
57
    void notifyDeleted() throws IllegalStateException ;
41
    
58
    
42
}
59
}
(-)projectapi/test/unit/src/org/netbeans/api/project/ProjectManagerTest.java (+71 lines)
Lines 373-376 Link Here
373
        }
373
        }
374
    }
374
    }
375
    
375
    
376
    public void testNotifyDeleted() throws Exception {
377
        FileObject p1 = scratch.createFolder("p1");
378
        FileObject p1TestProject = p1.createFolder("testproject");
379
        
380
        Project project1 = pm.findProject(p1);
381
        
382
        assertNotNull("project1 is recognized", project1);
383
        p1TestProject.delete();
384
        TestUtil.notifyDeleted(project1);
385
        
386
        assertFalse("project1 is not valid", pm.isValid(project1));
387
        assertNull("project1 is deleted", pm.findProject(p1));
388
389
        FileObject p2 = scratch.createFolder("p2");
390
        FileObject p2TestProject = p2.createFolder("testproject");
391
        
392
        Project project2 = pm.findProject(p2);
393
        
394
        assertNotNull("project2 is recognized", project2);
395
        TestUtil.notifyDeleted(project2);
396
        
397
        assertFalse("project2 is not valid", pm.isValid(project2));
398
        
399
        Project project2b = pm.findProject(p2);
400
        
401
        assertTrue("project2 is newly recognized", project2b != project2);
402
        assertNotNull("project2 is newly recognized", project2b);
403
404
        FileObject p3 = scratch.createFolder("p3");
405
        FileObject p3TestProject = p3.createFolder("testproject");
406
        
407
        Project project3 = pm.findProject(p3);
408
        
409
        assertNotNull("project3 is recognized", project3);
410
        TestUtil.modify(project3);
411
        assertTrue("project3 is modified", pm.isModified(project3));
412
        TestUtil.notifyDeleted(project3);
413
        
414
        assertFalse("project3 is not valid", pm.isValid(project3));
415
        
416
        boolean wasException = false;
417
        try {
418
            pm.isModified(project3);
419
        } catch (IllegalArgumentException e) {
420
            //the project is no longer recognized by the ProjectManager.
421
            wasException = true;
422
        }
423
        
424
        assertTrue("the project is no longer recognized by the ProjectManager", wasException);
425
        
426
        FileObject p4 = scratch.createFolder("p4");
427
        FileObject p4TestProject = p4.createFolder("testproject");
428
        
429
        Project project4 = pm.findProject(p4);
430
        
431
        assertNotNull("project4 is recognized", project4);
432
        TestUtil.notifyDeleted(project4);
433
        
434
        assertFalse("project4 is not valid", pm.isValid(project3));
435
        
436
        wasException = false;
437
        try {
438
            TestUtil.notifyDeleted(project4);
439
        } catch (IllegalStateException e) {
440
            //the project is no longer recognized by the ProjectManager.
441
            wasException = true;
442
        }
443
        
444
        assertTrue("An IllegalStateException was thrown when calling notifyDeleted twice.", wasException);
445
    }
446
    
376
}
447
}
(-)projectapi/test/unit/src/org/netbeans/api/project/TestUtil.java (+8 lines)
Lines 192-197 Link Here
192
    }
192
    }
193
    
193
    
194
    /**
194
    /**
195
     * Mark a test project as modified.
196
     * @param p a test project
197
     */
198
    public static void notifyDeleted(Project p) {
199
        ((TestProject)p).state.notifyDeleted();
200
    }
201
    
202
    /**
195
     * If set to something non-null, loading a broken project will wait for
203
     * If set to something non-null, loading a broken project will wait for
196
     * notification on this monitor before throwing an exception.
204
     * notification on this monitor before throwing an exception.
197
     * @see ProjectManagerTest#testLoadExceptionWithConcurrentLoad
205
     * @see ProjectManagerTest#testLoadExceptionWithConcurrentLoad
(-)projectui/src/org/netbeans/modules/project/ui/OpenProjectList.java (-1 / +5 lines)
Lines 735-741 Link Here
735
                if ( projectReference != null ) { // Reference to project exists
735
                if ( projectReference != null ) { // Reference to project exists
736
                    p = (Project)projectReference.get();
736
                    p = (Project)projectReference.get();
737
                    if ( p != null ) {
737
                    if ( p != null ) {
738
                        return p; // And refers to some project
738
                        // And refers to some project, check for validity:
739
                        if ( ProjectManager.getDefault().isValid( p ) )
740
                            return p; 
741
                        else
742
                            return null;
739
                    }
743
                    }
740
                }
744
                }
741
                
745
                
(-)projectui/src/org/netbeans/modules/project/ui/ProjectTab.java (-1 / +70 lines)
Lines 16-21 Link Here
16
import java.awt.BorderLayout;
16
import java.awt.BorderLayout;
17
import java.awt.Image;
17
import java.awt.Image;
18
import java.awt.Rectangle;
18
import java.awt.Rectangle;
19
import java.awt.event.ActionEvent;
20
import java.beans.PropertyChangeEvent;
21
import java.beans.PropertyChangeListener;
19
import java.beans.PropertyVetoException;
22
import java.beans.PropertyVetoException;
20
import java.io.IOException;
23
import java.io.IOException;
21
import java.io.ObjectInput;
24
import java.io.ObjectInput;
Lines 26-31 Link Here
26
import java.util.Iterator;
29
import java.util.Iterator;
27
import java.util.List;
30
import java.util.List;
28
import java.util.Map;
31
import java.util.Map;
32
import javax.swing.AbstractAction;
33
import javax.swing.Action;
29
import javax.swing.ActionMap;
34
import javax.swing.ActionMap;
30
import javax.swing.SwingUtilities;
35
import javax.swing.SwingUtilities;
31
import javax.swing.text.DefaultEditorKit;
36
import javax.swing.text.DefaultEditorKit;
Lines 33-38 Link Here
33
import javax.swing.tree.TreeNode;
38
import javax.swing.tree.TreeNode;
34
import javax.swing.tree.TreePath;
39
import javax.swing.tree.TreePath;
35
import javax.swing.tree.TreeModel;
40
import javax.swing.tree.TreeModel;
41
import org.netbeans.api.project.Project;
42
import org.netbeans.spi.project.ActionProvider;
36
import org.openide.ErrorManager;
43
import org.openide.ErrorManager;
37
import org.openide.awt.StatusDisplayer;
44
import org.openide.awt.StatusDisplayer;
38
import org.openide.explorer.ExplorerManager;
45
import org.openide.explorer.ExplorerManager;
Lines 87-93 Link Here
87
        map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(manager));
94
        map.put(DefaultEditorKit.copyAction, ExplorerUtils.actionCopy(manager));
88
        map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(manager));
95
        map.put(DefaultEditorKit.cutAction, ExplorerUtils.actionCut(manager));
89
        map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(manager));
96
        map.put(DefaultEditorKit.pasteAction, ExplorerUtils.actionPaste(manager));
90
        map.put("delete", ExplorerUtils.actionDelete(manager, true));
97
        map.put("delete", new DelegatingAction(ActionProvider.COMMAND_DELETE, ExplorerUtils.actionDelete(manager, true)));
91
        
98
        
92
        initComponents();
99
        initComponents();
93
        
100
        
Lines 525-530 Link Here
525
            catch ( NodeNotFoundException e ) {
532
            catch ( NodeNotFoundException e ) {
526
                return null;
533
                return null;
527
            }
534
            }
535
        }
536
        
537
    }
538
    
539
    private class DelegatingAction extends AbstractAction implements PropertyChangeListener {
540
        
541
        private Action explorerAction;
542
        private String projectAction;
543
        
544
        public DelegatingAction(String projectAction, Action explorerAction) {
545
            this.projectAction = projectAction;
546
            this.explorerAction = explorerAction;
547
            
548
            manager.addPropertyChangeListener(this);
549
            explorerAction.addPropertyChangeListener(this);
550
        }
551
        
552
        private boolean isProject() {
553
            Node[] nodes = manager.getSelectedNodes();
554
            
555
            if (nodes.length == 1) {
556
                return nodes[0].getParentNode() == rootNode;
557
            }
558
            
559
            return false;
560
        }
561
        
562
        public void actionPerformed(ActionEvent e) {
563
            if (isProject()) {
564
                Node[] nodes = manager.getSelectedNodes();
565
                Project p = (Project) nodes[0].getLookup().lookup(Project.class);
566
                
567
                assert p != null;
568
                
569
                ActionProvider ap = (ActionProvider) p.getLookup().lookup(ActionProvider.class);
570
                
571
                ap.invokeAction(projectAction, nodes[0].getLookup());
572
            } else {
573
                explorerAction.actionPerformed(e);
574
            }
575
        }
576
        
577
        public void updateIsEnabled() {
578
            if (isProject()) {
579
                Node[] nodes = manager.getSelectedNodes();
580
                Project p = (Project) nodes[0].getLookup().lookup(Project.class);
581
                
582
                if (p == null) {
583
                    setEnabled(false);
584
                }
585
                
586
                ActionProvider ap = (ActionProvider) p.getLookup().lookup(ActionProvider.class);
587
                
588
                setEnabled(ap.isActionEnabled(projectAction, nodes[0].getLookup()));
589
            } else {
590
                setEnabled(explorerAction.isEnabled());
591
            }
592
        }
593
        
594
        public void propertyChange(PropertyChangeEvent evt) {
595
            //a bit brute force:
596
            updateIsEnabled();
528
        }
597
        }
529
        
598
        
530
    }
599
    }
(-)projectui/src/org/netbeans/modules/project/ui/actions/Actions.java (-2 / +15 lines)
Lines 22-27 Link Here
22
import org.netbeans.modules.project.uiapi.ActionsFactory;
22
import org.netbeans.modules.project.uiapi.ActionsFactory;
23
import org.netbeans.spi.project.ActionProvider;
23
import org.netbeans.spi.project.ActionProvider;
24
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
24
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
25
import org.openide.actions.DeleteAction;
25
import org.openide.nodes.Node;
26
import org.openide.nodes.Node;
26
import org.openide.util.ContextAwareAction;
27
import org.openide.util.ContextAwareAction;
27
import org.openide.util.HelpCtx;
28
import org.openide.util.HelpCtx;
Lines 48-53 Link Here
48
    private static Action OPEN_SUBPROJECTS;
49
    private static Action OPEN_SUBPROJECTS;
49
    private static Action CLOSE_PROJECT;
50
    private static Action CLOSE_PROJECT;
50
    private static Action NEW_FILE;
51
    private static Action NEW_FILE;
52
    private static Action DELETE_PROJECT;
51
            
53
            
52
    public synchronized Action setAsMainProjectAction() {
54
    public synchronized Action setAsMainProjectAction() {
53
        if ( SET_AS_MAIN_PROJECT == null ) {
55
        if ( SET_AS_MAIN_PROJECT == null ) {
Lines 84-94 Link Here
84
        return NEW_FILE;
86
        return NEW_FILE;
85
    }    
87
    }    
86
    
88
    
89
    public Action deleteProjectAction() {
90
        return deleteProject();
91
    }
92
87
    public synchronized Action newProjectAction() {
93
    public synchronized Action newProjectAction() {
88
        return new NewProject();
94
        return new NewProject();
89
    }
95
    }
90
    
96
    
91
    
92
    public Action projectCommandAction(String command, String namePattern, Icon icon ) {
97
    public Action projectCommandAction(String command, String namePattern, Icon icon ) {
93
        return new ProjectAction( command, namePattern, icon, null );
98
        return new ProjectAction( command, namePattern, icon, null );
94
    }
99
    }
Lines 162-167 Link Here
162
        return a;
167
        return a;
163
    }
168
    }
164
    
169
    
170
    public static synchronized Action deleteProject() {
171
        if (DELETE_PROJECT == null) {
172
            DELETE_PROJECT = DeleteAction.get(DeleteAction.class);
173
        }
174
        
175
        return DELETE_PROJECT;
176
    }
177
    
165
    // 1-off actions -----------------------------------------------------------
178
    // 1-off actions -----------------------------------------------------------
166
    
179
    
167
    public static Action compileSingle() {
180
    public static Action compileSingle() {
Lines 257-261 Link Here
257
        a.putValue("iconBase","org/netbeans/modules/project/ui/resources/debugProject.gif"); //NOI18N
270
        a.putValue("iconBase","org/netbeans/modules/project/ui/resources/debugProject.gif"); //NOI18N
258
        return a;
271
        return a;
259
    }
272
    }
260
            
273
261
}
274
}
(-)projectui/src/org/netbeans/modules/project/ui/actions/Bundle.properties (+1 lines)
Lines 42-47 Link Here
42
LBL_TestProjectAction_Name=Test {0,choice,0#Project|1#"{1}"|1<{0} Projects}
42
LBL_TestProjectAction_Name=Test {0,choice,0#Project|1#"{1}"|1<{0} Projects}
43
LBL_CompileSingleAction_Name=Co&mpile {0,choice,0#File|1#"{1}"|1<Files}
43
LBL_CompileSingleAction_Name=Co&mpile {0,choice,0#File|1#"{1}"|1<Files}
44
LBL_StopBuildingAction_Name=&Stop Building
44
LBL_StopBuildingAction_Name=&Stop Building
45
LBL_DeleteProjectAction_Name=Delete {0,choice,0#Project|1#"{1}"|1<{0} Projects}
45
46
46
LBL_RunProjectAction_Name=Run {0,choice,0#Project|1#"{1}" Project|1<{0} Projects}
47
LBL_RunProjectAction_Name=Run {0,choice,0#Project|1#"{1}" Project|1<{0} Projects}
47
LBL_DebugProjectAction_Name=Run {0,choice,0#Project|1#"{1}" Project|1<{0} Projects} in Debugger
48
LBL_DebugProjectAction_Name=Run {0,choice,0#Project|1#"{1}" Project|1<{0} Projects} in Debugger
(-)projectui/src/org/netbeans/modules/project/ui/resources/layer.xml (-2 / +2 lines)
Lines 266-274 Link Here
266
                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>                 
266
                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>                 
267
            </file>
267
            </file>
268
            
268
            
269
            <!-- SetMain and customize -->
270
            
271
            <attr name="SeparatorOpen.instance/org-netbeans-modules-project-ui-SetMainProject.shadow" boolvalue="true" />
269
            <attr name="SeparatorOpen.instance/org-netbeans-modules-project-ui-SetMainProject.shadow" boolvalue="true" />
270
            
271
            <!-- SetMain and customize -->
272
            
272
            
273
            <file name="org-netbeans-modules-project-ui-SetMainProject.shadow">
273
            <file name="org-netbeans-modules-project-ui-SetMainProject.shadow">
274
                <attr name="originalFile" stringvalue="Actions/Project/org-netbeans-modules-project-ui-SetMainProject.instance"/>
274
                <attr name="originalFile" stringvalue="Actions/Project/org-netbeans-modules-project-ui-SetMainProject.instance"/>
(-)projectui/test/unit/src/org/netbeans/modules/project/ui/OpenProjectListTest.java (+36 lines)
Lines 177-182 Link Here
177
        assertEquals("both close hooks were called", 2, TestProjectOpenedHookImpl.closed);
177
        assertEquals("both close hooks were called", 2, TestProjectOpenedHookImpl.closed);
178
    }
178
    }
179
    
179
    
180
    public void testNotifyDeleted() throws Exception {
181
        FileObject workDir = FileUtil.toFileObject (getWorkDir ());
182
        
183
        FileObject p1 = workDir.createFolder("p1");
184
        FileObject p1TestProject = p1.createFolder("testproject");
185
        
186
        Project project1 = ProjectManager.getDefault().findProject(p1);
187
        
188
        assertNotNull("project1 is recognized", project1);
189
        
190
        OpenProjectList.getDefault().open(project1);
191
        
192
        OpenProjectList.getDefault().close(new Project[] {project1});
193
        
194
        p1TestProject.delete();
195
        TestSupport.notifyDeleted(project1);
196
        
197
        assertNull("project1 is deleted", ProjectManager.getDefault().findProject(p1));
198
        
199
        assertFalse("project1 is not in recent projects list", OpenProjectList.getDefault().getRecentProjects().contains(project1));
200
        
201
        FileObject p2 = workDir.createFolder("p2");
202
        FileObject p2TestProject = p2.createFolder("testproject");
203
        
204
        Project project2 = ProjectManager.getDefault().findProject(p2);
205
        
206
        assertNotNull("project2 is recognized", project2);
207
        OpenProjectList.getDefault().open(project1);
208
        
209
        OpenProjectList.getDefault().close(new Project[] {project1});
210
        
211
        TestSupport.notifyDeleted(project2);
212
        
213
        assertFalse("project2 is not in recent projects list", OpenProjectList.getDefault().getRecentProjects().contains(project2));
214
    }
215
    
180
    // helper code
216
    // helper code
181
217
182
    private static class MySubprojectProvider implements SubprojectProvider {
218
    private static class MySubprojectProvider implements SubprojectProvider {
(-)projectui/test/unit/src/org/netbeans/modules/project/ui/actions/TestSupport.java (+3 lines)
Lines 50-55 Link Here
50
        return new TestProjectFactory();
50
        return new TestProjectFactory();
51
    }
51
    }
52
    
52
    
53
    public static void notifyDeleted(Project p) {
54
        ((TestProject) p).state.notifyDeleted();
55
    }
53
        
56
        
54
    private static final class TestProjectFactory implements ProjectFactory {
57
    private static final class TestProjectFactory implements ProjectFactory {
55
        
58
        
(-)projectuiapi/apichanges.xml (+16 lines)
Lines 76-81 Link Here
76
76
77
    <changes>
77
    <changes>
78
78
79
        <change id="action-delete-added">
80
            <api name="general"/>
81
            <summary>Delete Action Added</summary>
82
            <version major="1" minor="4"/>
83
            <date day="20" month="6" year="2005"/>
84
            <author login="jlahoda"/>
85
            <compatibility addition="yes" />
86
            <description>            
87
                Introduced:
88
                <ul>
89
                    <li><code>CommonProjectActions.deleteProjectAction</code> method</li>
90
                </ul>                
91
            </description>
92
            <issue number="51468" />            
93
        </change>
94
        
79
        <change id="CommonProjectActions.EXISTING_SOURCES_FOLDER">
95
        <change id="CommonProjectActions.EXISTING_SOURCES_FOLDER">
80
            <api name="general"/>
96
            <api name="general"/>
81
            <summary>New Project Wizard Action</summary>
97
            <summary>New Project Wizard Action</summary>
(-)projectuiapi/src/org/netbeans/modules/project/uiapi/ActionsFactory.java (+2 lines)
Lines 35-40 Link Here
35
    
35
    
36
    public Action newFileAction();
36
    public Action newFileAction();
37
    
37
    
38
    public Action deleteProjectAction();
39
    
38
    public Action newProjectAction();
40
    public Action newProjectAction();
39
            
41
            
40
    // Actions sensitive to project selection
42
    // Actions sensitive to project selection
(-)projectuiapi/src/org/netbeans/spi/project/ui/support/CommonProjectActions.java (+14 lines)
Lines 99-104 Link Here
99
    }
99
    }
100
    
100
    
101
    /**
101
    /**
102
     * Create an action "Delete Project".
103
     * It should be invoked with an action context containing
104
     * one or more {@link org.netbeans.api.project.Project}s.
105
     * <p class="nonnormative">
106
     * You might include this in the context menu of a logical view.
107
     * </p>
108
     * @since 1.4
109
     * @return an action
110
     */
111
    public static Action deleteProjectAction() {
112
        return Utilities.getActionsFactory().deleteProjectAction();
113
    }
114
115
    /**
102
     * Creates action that invokes <b>New Project</b> wizard.
116
     * Creates action that invokes <b>New Project</b> wizard.
103
     * 
117
     * 
104
     * <p>{@link #EXISTING_SOURCES_FOLDER} keyed action
118
     * <p>{@link #EXISTING_SOURCES_FOLDER} keyed action

Return to bug 58866