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 71515
Collapse All | Expand All

(-)a/java.api.common/src/org/netbeans/modules/java/api/common/project/BaseActionProvider.java (+2 lines)
Lines 45-50 Link Here
45
package org.netbeans.modules.java.api.common.project;
45
package org.netbeans.modules.java.api.common.project;
46
46
47
import java.awt.Dialog;
47
import java.awt.Dialog;
48
import java.awt.EventQueue;
48
import java.awt.event.MouseEvent;
49
import java.awt.event.MouseEvent;
49
import java.beans.PropertyChangeEvent;
50
import java.beans.PropertyChangeEvent;
50
import java.beans.PropertyChangeListener;
51
import java.beans.PropertyChangeListener;
Lines 384-389 Link Here
384
385
385
    @Override
386
    @Override
386
    public void invokeAction( final String command, final Lookup context ) throws IllegalArgumentException {
387
    public void invokeAction( final String command, final Lookup context ) throws IllegalArgumentException {
388
        assert EventQueue.isDispatchThread();
387
        if (COMMAND_DELETE.equals(command)) {
389
        if (COMMAND_DELETE.equals(command)) {
388
            DefaultProjectOperations.performDefaultDeleteOperation(project);
390
            DefaultProjectOperations.performDefaultDeleteOperation(project);
389
            return ;
391
            return ;
(-)a/projectui/nbproject/project.xml (-1 / +1 lines)
Lines 108-114 Link Here
108
                    <compile-dependency/>
108
                    <compile-dependency/>
109
                    <run-dependency>
109
                    <run-dependency>
110
                        <release-version>1</release-version>
110
                        <release-version>1</release-version>
111
                        <specification-version>1.33</specification-version>
111
                        <specification-version>1.43</specification-version>
112
                    </run-dependency>
112
                    </run-dependency>
113
                </dependency>
113
                </dependency>
114
                <dependency>
114
                <dependency>
(-)a/projectui/src/org/netbeans/modules/project/ui/actions/ActionsUtil.java (-1 / +2 lines)
Lines 48-53 Link Here
48
import java.util.Arrays;
48
import java.util.Arrays;
49
import java.util.HashMap;
49
import java.util.HashMap;
50
import java.util.HashSet;
50
import java.util.HashSet;
51
import java.util.LinkedHashSet;
51
import java.util.List;
52
import java.util.List;
52
import java.util.Map;
53
import java.util.Map;
53
import java.util.Set;
54
import java.util.Set;
Lines 90-96 Link Here
90
         */
91
         */
91
        // #74161: do not cache
92
        // #74161: do not cache
92
        // First find out whether there is a project directly in the Lookup
93
        // First find out whether there is a project directly in the Lookup
93
        Set<Project> result = new HashSet<Project>();
94
        Set<Project> result = new LinkedHashSet<Project>(); // XXX or use OpenProjectList.projectByDisplayName?
94
        for (Project p : lookup.lookupAll(Project.class)) {
95
        for (Project p : lookup.lookupAll(Project.class)) {
95
            result.add(p);
96
            result.add(p);
96
        }
97
        }
(-)a/projectui/src/org/netbeans/modules/project/ui/actions/FileAction.java (+1 lines)
Lines 113-118 Link Here
113
            r[0] = new Runnable() {
113
            r[0] = new Runnable() {
114
                @Override public void run() {
114
                @Override public void run() {
115
                    Project[] projects = ActionsUtil.getProjectsFromLookup( context, command );
115
                    Project[] projects = ActionsUtil.getProjectsFromLookup( context, command );
116
                    // XXX #64991: handle >1 project (tricky since must pass subset of selection to each)
116
                    if ( projects.length != 1 ) {
117
                    if ( projects.length != 1 ) {
117
                        if (projects.length == 0 && globalProvider(context) != null) {
118
                        if (projects.length == 0 && globalProvider(context) != null) {
118
                            enable[0] = true;
119
                            enable[0] = true;
(-)a/projectui/src/org/netbeans/modules/project/ui/actions/MainProjectAction.java (-93 / +55 lines)
Lines 44-61 Link Here
44
44
45
package org.netbeans.modules.project.ui.actions;
45
package org.netbeans.modules.project.ui.actions;
46
46
47
import java.awt.Toolkit;
48
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeEvent;
49
import java.beans.PropertyChangeListener;
48
import java.beans.PropertyChangeListener;
50
import java.text.MessageFormat;
49
import java.text.MessageFormat;
51
import java.util.Arrays;
50
import java.util.Arrays;
51
import java.util.LinkedList;
52
import javax.swing.Icon;
52
import javax.swing.Icon;
53
import org.netbeans.api.project.Project;
53
import org.netbeans.api.project.Project;
54
import org.netbeans.api.project.ProjectUtils;
55
import org.netbeans.api.project.ui.OpenProjects;
54
import org.netbeans.api.project.ui.OpenProjects;
56
import org.netbeans.modules.project.ui.OpenProjectList;
55
import org.netbeans.modules.project.ui.OpenProjectList;
57
import static org.netbeans.modules.project.ui.actions.Bundle.*;
56
import static org.netbeans.modules.project.ui.actions.Bundle.*;
58
import org.netbeans.spi.project.ActionProvider;
59
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
57
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
60
import org.openide.DialogDisplayer;
58
import org.openide.DialogDisplayer;
61
import org.openide.NotifyDescriptor;
59
import org.openide.NotifyDescriptor;
Lines 66-74 Link Here
66
import org.openide.util.NbBundle.Messages;
64
import org.openide.util.NbBundle.Messages;
67
import org.openide.util.WeakListeners;
65
import org.openide.util.WeakListeners;
68
66
69
/** Invokes command on the main project.
67
/**
70
 *
68
 * Similar to {@link ProjectAction} but has a different selection model.
71
 * @author Pet Hrebejk
69
 * First uses the main project, if set.
70
 * Else uses the selected projects, if any.
71
 * Finally, if just one project is open, uses that.
72
 */
72
 */
73
public class MainProjectAction extends LookupSensitiveAction implements PropertyChangeListener {
73
public class MainProjectAction extends LookupSensitiveAction implements PropertyChangeListener {
74
74
Lines 85-91 Link Here
85
    }
85
    }
86
86
87
    @SuppressWarnings("LeakingThisInConstructor")
87
    @SuppressWarnings("LeakingThisInConstructor")
88
    public MainProjectAction(String command, ProjectActionPerformer performer, String name, Icon icon) {
88
    private MainProjectAction(String command, ProjectActionPerformer performer, String name, Icon icon) {
89
89
90
        super(icon, null, new Class<?>[] {Project.class, DataObject.class});
90
        super(icon, null, new Class<?>[] {Project.class, DataObject.class});
91
        this.command = command;
91
        this.command = command;
Lines 117-170 Link Here
117
117
118
    @Messages("MainProjectAction.no_main=Set a main project, or select one project or project file, or keep just one project open.")
118
    @Messages("MainProjectAction.no_main=Set a main project, or select one project or project file, or keep just one project open.")
119
    public @Override void actionPerformed(Lookup context) {
119
    public @Override void actionPerformed(Lookup context) {
120
        // first try to find main project
120
        Project mainProject = OpenProjectList.getDefault().getMainProject();
121
        Project p = OpenProjectList.getDefault().getMainProject();
121
        Project[] projects = selection(mainProject, context);
122
123
        // then try to find some selected project
124
        if (p == null) {
125
            Project[] projects = ActionsUtil.getProjectsFromLookup(context, command);
126
            if (projects.length == 1) {
127
                p = projects[0];
128
            }
129
        }
130
131
        // then if there is only one project opened in IDE - use it
132
        if (p == null) {
133
            Project[] projects = OpenProjects.getDefault().getOpenProjects();
134
            if (projects.length == 1) {
135
                p = projects[0];
136
            }
137
        }
138
122
139
        // if no main project or no selected or more than one project opened,
123
        // if no main project or no selected or more than one project opened,
140
        // then show warning
124
        // then show warning
141
        if (p == null) {
125
        if (projects.length == 0) {
142
            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(MainProjectAction_no_main(), NotifyDescriptor.WARNING_MESSAGE));
126
            DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(MainProjectAction_no_main(), NotifyDescriptor.WARNING_MESSAGE));
143
            return;
127
            return;
144
        }
128
        }
145
129
146
        if ( command != null ) {
130
        if (command != null && projects.length > 0) {
147
            ActionProvider ap = p.getLookup().lookup(ActionProvider.class);
131
            ProjectAction.runSequentially(new LinkedList<Project>(Arrays.asList(projects)), this, command);
148
            if (ap != null) {
132
        } else if (performer != null && projects.length == 1) {
149
                if (Arrays.asList(ap.getSupportedActions()).contains(command)) {
133
            performer.perform(projects[0]);
150
                    ap.invokeAction(command, Lookup.EMPTY);
151
                } else {
152
                    // #47160: was a supported command (e.g. on a freeform project) but was then removed.
153
                    Toolkit.getDefaultToolkit().beep();
154
                    refreshView(null, false);
155
                }
156
            }
157
        }
158
        else {
159
            performer.perform( p );
160
        }
134
        }
161
    }
135
    }
162
136
163
164
    // Private methods ---------------------------------------------------------
165
166
    // Implementation of PropertyChangeListener --------------------------------
167
168
    public @Override void propertyChange( PropertyChangeEvent evt ) {
137
    public @Override void propertyChange( PropertyChangeEvent evt ) {
169
        if (OpenProjectList.PROPERTY_MAIN_PROJECT.equals(evt.getPropertyName()) ||
138
        if (OpenProjectList.PROPERTY_MAIN_PROJECT.equals(evt.getPropertyName()) ||
170
            OpenProjectList.PROPERTY_OPEN_PROJECTS.equals(evt.getPropertyName())) {
139
            OpenProjectList.PROPERTY_OPEN_PROJECTS.equals(evt.getPropertyName())) {
Lines 172-221 Link Here
172
        }
141
        }
173
    }
142
    }
174
143
144
    private Project[] selection(Project mainProject, Lookup context) {
145
        if (mainProject != null) {
146
            return new Project[] {mainProject};
147
        }
148
        Lookup theContext = context;
149
        if (theContext == null) {
150
            theContext = LastActivatedWindowLookup.INSTANCE;
151
        }
152
        if (theContext != null) {
153
            Project[] projects = ActionsUtil.getProjectsFromLookup(theContext, command);
154
            if (projects.length > 0) {
155
                return projects;
156
            }
157
        }
158
        Project[] projects = OpenProjects.getDefault().getOpenProjects();
159
        if (projects.length == 1) {
160
            return projects;
161
        }
162
        return new Project[0];
163
    }
164
175
    private void refreshView(final Lookup context, boolean immediate) {
165
    private void refreshView(final Lookup context, boolean immediate) {
176
        Runnable r= new Runnable() {
166
        Runnable r= new Runnable() {
177
            public @Override void run() {
167
            public @Override void run() {
178
168
179
        Project p = OpenProjectList.getDefault().getMainProject();
169
        Project mainProject = OpenProjectList.getDefault().getMainProject();
180
        Lookup theContext = context;
170
        Project[] projects = selection(mainProject, context);
181
171
182
        if (p == null) {
172
        final String presenterName = getPresenterName(name, mainProject, projects);
183
            if (theContext == null) {
184
                theContext = LastActivatedWindowLookup.INSTANCE;
185
            }
186
            if (theContext != null) {
187
                Project[] projects = ActionsUtil.getProjectsFromLookup(theContext, command);
188
                if (projects.length == 1) {
189
                    p = projects[0];
190
                }
191
            }
192
        }
193
194
        if (p == null) {
195
            Project[] projects = OpenProjects.getDefault().getOpenProjects();
196
            if (projects.length == 1) {
197
                p = projects[0];
198
            }
199
        }
200
201
        Project mainProject = OpenProjectList.getDefault().getMainProject();
202
203
        final String presenterName = getPresenterName(name, mainProject, p);
204
        final boolean enabled;
173
        final boolean enabled;
205
174
206
        if ( command == null ) {
175
        if ( command == null ) {
207
            enabled = performer.enable(p);
176
            enabled = projects.length == 1 && performer.enable(projects[0]);
208
        }
177
        }
209
        else {
178
        else if (projects.length == 0) {
210
            if ( p == null ) {
179
            enabled = false;
211
                enabled = false;
180
        } else {
181
            boolean e = true;
182
            for (Project p : projects) {
183
                if (!ActionsUtil.commandSupported(p, command, Lookup.EMPTY)) {
184
                    e = false;
185
                    break;
186
                }
212
            }
187
            }
213
            else if ( ActionsUtil.commandSupported ( p, command, Lookup.EMPTY ) ) {
188
            enabled = e;
214
                enabled = true;
215
            }
216
            else {
217
                enabled = false;
218
            }
219
        }
189
        }
220
190
221
        Mutex.EVENT.writeAccess(new Runnable() {
191
        Mutex.EVENT.writeAccess(new Runnable() {
Lines 234-255 Link Here
234
        }
204
        }
235
    }
205
    }
236
206
237
    private String getPresenterName(String name, Project mPrj, Project cPrj) {
207
    private String getPresenterName(String name, Project mPrj, Project[] cPrj) {
238
        String toReturn = "";
208
        if (name == null) {
239
        Object[] formatterArgs;
209
            return "";
240
        if (mPrj == null) {
210
        } else if (mPrj == null) {
241
            if (cPrj == null) {
211
            return ActionsUtil.formatProjectSensitiveName(name, cPrj);
242
                formatterArgs = new Object[] { 0 };
243
            } else {
244
                formatterArgs = new Object[] { 1, ProjectUtils.getInformation(cPrj).getDisplayName() };
245
            }
246
        } else {
212
        } else {
247
            formatterArgs = new Object[] { -1 };
213
            return MessageFormat.format(name, -1);
248
        }
214
        }
249
        if (name != null) {
250
            toReturn = MessageFormat.format(name, formatterArgs);
251
        }
252
        return toReturn;
253
    }
215
    }
254
216
255
    @Override
217
    @Override
(-)a/projectui/src/org/netbeans/modules/project/ui/actions/ProjectAction.java (-20 / +57 lines)
Lines 44-54 Link Here
44
44
45
package org.netbeans.modules.project.ui.actions;
45
package org.netbeans.modules.project.ui.actions;
46
46
47
import java.awt.Toolkit;
48
import java.util.Arrays;
49
import java.util.LinkedList;
50
import java.util.Queue;
51
import java.util.concurrent.atomic.AtomicBoolean;
47
import java.util.logging.Level;
52
import java.util.logging.Level;
48
import java.util.logging.LogRecord;
53
import java.util.logging.LogRecord;
49
import javax.swing.Action;
54
import javax.swing.Action;
50
import javax.swing.Icon;
55
import javax.swing.Icon;
51
import org.netbeans.api.project.Project;
56
import org.netbeans.api.project.Project;
57
import org.netbeans.spi.project.ActionProgress;
52
import org.netbeans.spi.project.ActionProvider;
58
import org.netbeans.spi.project.ActionProvider;
53
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
59
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
54
import org.openide.awt.Actions;
60
import org.openide.awt.Actions;
Lines 58-63 Link Here
58
import org.openide.util.Lookup;
64
import org.openide.util.Lookup;
59
import org.openide.util.Mutex;
65
import org.openide.util.Mutex;
60
import org.openide.util.NbBundle;
66
import org.openide.util.NbBundle;
67
import org.openide.util.lookup.Lookups;
61
68
62
/** Action sensitive to current project
69
/** Action sensitive to current project
63
 * 
70
 * 
Lines 118-143 Link Here
118
    @Override
125
    @Override
119
    protected void actionPerformed( Lookup context ) {
126
    protected void actionPerformed( Lookup context ) {
120
        Project[] projects = ActionsUtil.getProjectsFromLookup( context, command );
127
        Project[] projects = ActionsUtil.getProjectsFromLookup( context, command );
121
        
128
        if (command != null && projects.length > 0) {
122
        if ( projects.length == 1 ) {
129
            runSequentially(new LinkedList<Project>(Arrays.asList(projects)), this, command);
123
            if ( command != null ) {
130
        } else if (performer != null && projects.length == 1) {
124
                ActionProvider ap = projects[0].getLookup().lookup(ActionProvider.class);
131
            performer.perform(projects[0]);
125
                LogRecord r = new LogRecord(Level.FINE, "PROJECT_ACTION"); // NOI18N
132
        }
126
                r.setResourceBundle(NbBundle.getBundle(ProjectAction.class));
133
    }
127
                r.setParameters(new Object[] {
134
    static void runSequentially(final Queue<Project> queue, final LookupSensitiveAction a, final String command) {
128
                    getClass().getName(),
135
        Project p = queue.remove();
129
                    projects[0].getClass().getName(),
136
        final ActionProvider ap = p.getLookup().lookup(ActionProvider.class);
130
                    getValue(NAME)
137
        if (ap == null) {
131
                });
138
            return;
132
                r.setLoggerName(UILOG.getName());
139
        }
133
                UILOG.log(r);
140
        if (!Arrays.asList(ap.getSupportedActions()).contains(command)) {
134
                ap.invokeAction( command, Lookup.EMPTY );        
141
            // #47160: was a supported command (e.g. on a freeform project) but was then removed.
142
            Toolkit.getDefaultToolkit().beep();
143
            a.refresh(a.getLookup(), false);
144
            return;
145
        }
146
        LogRecord r = new LogRecord(Level.FINE, "PROJECT_ACTION"); // NOI18N
147
        r.setResourceBundle(NbBundle.getBundle(ProjectAction.class));
148
        r.setParameters(new Object[] {
149
            a.getClass().getName(),
150
            p.getClass().getName(),
151
            a.getValue(NAME)
152
        });
153
        r.setLoggerName(UILOG.getName());
154
        UILOG.log(r);
155
        Mutex.EVENT.writeAccess(new Runnable() {
156
            @Override public void run() {
157
                if (queue.isEmpty()) {
158
                    ap.invokeAction(command, Lookup.EMPTY);
159
                } else {
160
                    final AtomicBoolean started = new AtomicBoolean();
161
                    ap.invokeAction(command, Lookups.singleton(new ActionProgress() {
162
                        @Override protected void started() {
163
                            started.set(true);
164
                        }
165
                        @Override public void finished(boolean success) {
166
                            if (success) { // OK, next...
167
                                runSequentially(queue, a, command);
168
                            } // else build failed, so skip others
169
                        }
170
                    }));
171
                    if (!started.get()) {
172
                        // Did not run action for some reason; try others?
173
                        runSequentially(queue, a, command);
174
                    }
175
                }
135
            }
176
            }
136
            else if ( performer != null ) {
177
        });
137
                performer.perform( projects[0] );
138
            }
139
        }
140
        
141
    }
178
    }
142
    
179
    
143
    @Override
180
    @Override
Lines 147-153 Link Here
147
        Project[] projects = ActionsUtil.getProjectsFromLookup( context, command );
184
        Project[] projects = ActionsUtil.getProjectsFromLookup( context, command );
148
        final boolean enable;
185
        final boolean enable;
149
        if ( command != null ) {
186
        if ( command != null ) {
150
            enable = projects.length == 1;
187
            enable = projects.length > 0;
151
        } else if ( performer != null && projects.length == 1 ) {
188
        } else if ( performer != null && projects.length == 1 ) {
152
            enable = performer.enable(projects[0]);
189
            enable = performer.enable(projects[0]);
153
        } else {
190
        } else {
(-)a/projectui/test/unit/src/org/netbeans/modules/project/ui/actions/MainProjectActionTest.java (+120 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.project.ui.actions;
44
45
import java.util.ArrayList;
46
import java.util.List;
47
import org.netbeans.api.annotations.common.SuppressWarnings;
48
import org.netbeans.api.project.ProjectManager;
49
import org.netbeans.junit.NbTestCase;
50
import org.netbeans.spi.project.ActionProgress;
51
import org.netbeans.spi.project.ActionProvider;
52
import org.openide.filesystems.FileObject;
53
import org.openide.filesystems.FileUtil;
54
import org.openide.util.Lookup;
55
import org.openide.util.lookup.Lookups;
56
import org.openide.util.test.MockLookup;
57
58
public class MainProjectActionTest extends NbTestCase {
59
60
    public MainProjectActionTest(String name) {
61
        super(name);
62
    }
63
64
    @Override protected boolean runInEQ() {
65
        return true;
66
    }
67
68
    private FileObject p1, p2;
69
    private TestSupport.TestProject prj1, prj2;
70
71
    @Override protected void setUp() throws Exception {
72
        MockLookup.setInstances(new TestSupport.TestProjectFactory());
73
        FileObject r = FileUtil.createMemoryFileSystem().getRoot();
74
        p1 = TestSupport.createTestProject(r, "p1");
75
        prj1 = (TestSupport.TestProject) ProjectManager.getDefault().findProject(p1);
76
        p2 = TestSupport.createTestProject(r, "p2");
77
        prj2 = (TestSupport.TestProject) ProjectManager.getDefault().findProject(p2);
78
    }
79
80
    @SuppressWarnings({"UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR", "SIC_INNER_SHOULD_BE_STATIC_ANON"})
81
    public void testSeqRun() throws Exception {
82
        final String CMD = "cmd";
83
        final List<Integer> invocations = new ArrayList<Integer>();
84
        class BlockingRun implements ActionProvider {
85
            final int which;
86
            final boolean success;
87
            BlockingRun(int which, boolean success) {
88
                this.which = which;
89
                this.success = success;
90
            }
91
            @Override public String[] getSupportedActions() {
92
                return new String[] {CMD};
93
            }
94
            @Override public boolean isActionEnabled(String command, Lookup context) {
95
                return true;
96
            }
97
            @Override public void invokeAction(String command, Lookup context) {
98
                ActionProgress listener = ActionProgress.start(context);
99
                invocations.add(which);
100
                listener.finished(success);
101
            }
102
        }
103
        BlockingRun ap1 = new BlockingRun(1, true);
104
        prj1.setLookup(Lookups.singleton(ap1));
105
        BlockingRun ap2 = new BlockingRun(2, true);
106
        prj2.setLookup(Lookups.singleton(ap2));
107
        LookupSensitiveAction a = new MainProjectAction(CMD, "a", null);
108
        a.actionPerformed(Lookups.fixed(prj1, prj2));
109
        assertEquals("[1, 2]", invocations.toString());
110
        ap2 = new BlockingRun(2, false);
111
        prj2.setLookup(Lookups.singleton(ap2));
112
        a.actionPerformed(Lookups.fixed(prj1, prj2));
113
        assertEquals("[1, 2, 1, 2]", invocations.toString());
114
        ap1 = new BlockingRun(1, false);
115
        prj1.setLookup(Lookups.singleton(ap1));
116
        a.actionPerformed(Lookups.fixed(prj1, prj2));
117
        assertEquals("[1, 2, 1, 2, 1]", invocations.toString());
118
    }
119
120
}
(-)a/projectui/test/unit/src/org/netbeans/modules/project/ui/actions/ProjectActionTest.java (-2 / +26 lines)
Lines 47-57 Link Here
47
import java.util.ArrayList;
47
import java.util.ArrayList;
48
import java.util.List;
48
import java.util.List;
49
import javax.swing.Action;
49
import javax.swing.Action;
50
import javax.swing.KeyStroke;
51
import org.netbeans.api.project.Project;
50
import org.netbeans.api.project.Project;
52
import org.netbeans.api.project.ProjectManager;
51
import org.netbeans.api.project.ProjectManager;
53
import org.netbeans.junit.MockServices;
52
import org.netbeans.junit.MockServices;
54
import org.netbeans.junit.NbTestCase;
53
import org.netbeans.junit.NbTestCase;
54
import org.netbeans.spi.project.ActionProgress;
55
import org.netbeans.spi.project.ActionProvider;
55
import org.netbeans.spi.project.ActionProvider;
56
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
56
import org.netbeans.spi.project.ui.support.ProjectActionPerformer;
57
import org.openide.filesystems.FileObject;
57
import org.openide.filesystems.FileObject;
Lines 77-82 Link Here
77
    private DataObject d2_1;
77
    private DataObject d2_1;
78
    private DataObject d2_2;
78
    private DataObject d2_2;
79
    private TestSupport.TestProject project1;
79
    private TestSupport.TestProject project1;
80
    private TestActionProvider tap1;
80
    private TestSupport.TestProject project2;
81
    private TestSupport.TestProject project2;
81
82
82
    @Override protected boolean runInEQ() {
83
    @Override protected boolean runInEQ() {
Lines 98-104 Link Here
98
        d1_2 = DataObject.find(f1_2);
99
        d1_2 = DataObject.find(f1_2);
99
               
100
               
100
        project1 = (TestSupport.TestProject)ProjectManager.getDefault().findProject( p1 );
101
        project1 = (TestSupport.TestProject)ProjectManager.getDefault().findProject( p1 );
101
        project1.setLookup( Lookups.fixed( new Object[] { new TestActionProvider() } ) );  
102
        tap1 = new TestActionProvider();
103
        project1.setLookup(Lookups.singleton(tap1));
102
        
104
        
103
        p2 = TestSupport.createTestProject( workDir, "project2" );
105
        p2 = TestSupport.createTestProject( workDir, "project2" );
104
        f2_1 = p2.createData("f2_1.java");
106
        f2_1 = p2.createData("f2_1.java");
Lines 125-130 Link Here
125
        assertEnablement(action, false);
127
        assertEnablement(action, false);
126
        lookup.change(d1_1, d2_1);
128
        lookup.change(d1_1, d2_1);
127
        assertEnablement(action, false);
129
        assertEnablement(action, false);
130
        TestActionProvider tap2 = new TestActionProvider();
131
        project2.setLookup(Lookups.singleton(tap2));
132
        lookup.change(d2_1);
133
        assertEnablement(action, true);
134
        lookup.change(d1_1, d2_1);
135
        assertEnablement(action, true);
136
        action.actionPerformed(null);
137
        assertEquals("[COMMAND]", tap1.invocations.toString());
138
        assertEquals("[COMMAND]", tap2.invocations.toString());
139
        tap1.listenerSuccess = true;
140
        tap2.listenerSuccess = true;
141
        action.actionPerformed(null);
142
        assertEquals("[COMMAND, COMMAND]", tap1.invocations.toString());
143
        assertEquals("[COMMAND, COMMAND]", tap2.invocations.toString());
144
        tap1.listenerSuccess = false;
145
        action.actionPerformed(null);
146
        assertEquals("[COMMAND, COMMAND, COMMAND]", tap1.invocations.toString());
147
        assertEquals("[COMMAND, COMMAND]", tap2.invocations.toString());
128
    }
148
    }
129
    
149
    
130
    public void testProviderEnablement() throws Exception {
150
    public void testProviderEnablement() throws Exception {
Lines 177-182 Link Here
177
        private String[] ACTIONS = new String[] { COMMAND };
197
        private String[] ACTIONS = new String[] { COMMAND };
178
        
198
        
179
        private List<String> invocations = new ArrayList<String>();
199
        private List<String> invocations = new ArrayList<String>();
200
        Boolean listenerSuccess;
180
        
201
        
181
        public String[] getSupportedActions() {
202
        public String[] getSupportedActions() {
182
            return ACTIONS;
203
            return ACTIONS;
Lines 186-191 Link Here
186
            
207
            
187
            if ( COMMAND.equals( command ) ) {
208
            if ( COMMAND.equals( command ) ) {
188
                invocations.add( command );
209
                invocations.add( command );
210
                if (listenerSuccess != null) {
211
                    ActionProgress.start(context).finished(listenerSuccess);
212
                }
189
            }            
213
            }            
190
            else {
214
            else {
191
                throw new IllegalArgumentException();
215
                throw new IllegalArgumentException();

Return to bug 71515