001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.apisupport.project.ui;
043:
044: import java.io.IOException;
045: import java.util.ArrayList;
046: import java.util.Arrays;
047: import java.util.Collection;
048: import java.util.List;
049: import javax.swing.Action;
050: import javax.swing.JSeparator;
051: import org.apache.tools.ant.module.api.support.ActionUtils;
052: import org.netbeans.api.project.Project;
053: import org.netbeans.modules.apisupport.project.NbModuleProject;
054: import org.netbeans.modules.apisupport.project.Util;
055: import org.netbeans.modules.apisupport.project.suite.SuiteProject;
056: import org.netbeans.modules.apisupport.project.ui.customizer.SuiteCustomizer;
057: import org.netbeans.modules.apisupport.project.universe.NbPlatform;
058: import org.netbeans.spi.project.ActionProvider;
059: import org.netbeans.spi.project.SubprojectProvider;
060: import org.netbeans.spi.project.support.ant.GeneratedFilesHelper;
061: import org.netbeans.spi.project.ui.support.CommonProjectActions;
062: import org.netbeans.spi.project.ui.support.DefaultProjectOperations;
063: import org.netbeans.spi.project.ui.support.ProjectSensitiveActions;
064: import org.openide.NotifyDescriptor;
065: import org.openide.actions.FindAction;
066: import org.openide.execution.ExecutorTask;
067: import org.openide.filesystems.FileObject;
068: import org.openide.util.Lookup;
069: import org.openide.util.NbBundle;
070: import org.openide.util.actions.SystemAction;
071: import org.openide.util.lookup.Lookups;
072:
073: /**
074: * Defines actions available on a suite.
075: * @author Jesse Glick
076: */
077: public final class SuiteActions implements ActionProvider {
078:
079: static Action[] getProjectActions(SuiteProject project) {
080: List<Action> actions = new ArrayList<Action>();
081: actions.add(CommonProjectActions.newFileAction());
082: actions.add(null);
083: actions.add(ProjectSensitiveActions
084: .projectCommandAction(ActionProvider.COMMAND_BUILD,
085: NbBundle.getMessage(SuiteActions.class,
086: "SUITE_ACTION_build"), null));
087: actions.add(ProjectSensitiveActions.projectCommandAction(
088: ActionProvider.COMMAND_REBUILD, NbBundle.getMessage(
089: SuiteActions.class, "SUITE_ACTION_rebuild"),
090: null));
091: actions.add(ProjectSensitiveActions
092: .projectCommandAction(ActionProvider.COMMAND_CLEAN,
093: NbBundle.getMessage(SuiteActions.class,
094: "SUITE_ACTION_clean"), null));
095: actions.add(null);
096: actions.add(ProjectSensitiveActions.projectCommandAction(
097: ActionProvider.COMMAND_RUN, NbBundle.getMessage(
098: SuiteActions.class, "SUITE_ACTION_run"), null));
099: actions.add(ProjectSensitiveActions
100: .projectCommandAction(ActionProvider.COMMAND_DEBUG,
101: NbBundle.getMessage(SuiteActions.class,
102: "SUITE_ACTION_debug"), null));
103: addFromLayers(actions, "Projects/Profiler_Actions_temporary"); //NOI18N
104: actions.add(null);
105: NbPlatform platform = project.getPlatform(true); //true -> #96095
106: if (platform != null
107: && platform.getHarnessVersion() >= NbPlatform.HARNESS_VERSION_61) {
108: actions.add(ProjectSensitiveActions.projectCommandAction(
109: ActionProvider.COMMAND_TEST, NbBundle.getMessage(
110: SuiteActions.class, "SUITE_ACTION_test"),
111: null));
112: actions.add(null);
113: }
114: actions.add(ProjectSensitiveActions.projectCommandAction(
115: "build-zip", NbBundle.getMessage(SuiteActions.class,
116: "SUITE_ACTION_zip"), null));
117: actions.add(null);
118: actions.add(ProjectSensitiveActions.projectCommandAction(
119: "build-jnlp", NbBundle.getMessage(SuiteActions.class,
120: "SUITE_ACTION_build_jnlp"), null));
121: actions.add(ProjectSensitiveActions.projectCommandAction(
122: "run-jnlp", NbBundle.getMessage(SuiteActions.class,
123: "SUITE_ACTION_run_jnlp"), null));
124: actions.add(ProjectSensitiveActions.projectCommandAction(
125: "debug-jnlp", NbBundle.getMessage(SuiteActions.class,
126: "SUITE_ACTION_debug_jnlp"), null));
127: actions.add(null);
128: if (platform != null
129: && platform.getHarnessVersion() >= NbPlatform.HARNESS_VERSION_55u1) {
130: actions.add(ProjectSensitiveActions.projectCommandAction(
131: "build-mac", NbBundle.getMessage(
132: SuiteActions.class, "SUITE_ACTION_mac"),
133: null));
134: actions.add(null);
135: }
136: if (platform != null
137: && platform.getHarnessVersion() >= NbPlatform.HARNESS_VERSION_50u1) { // #71631
138: actions.add(ProjectSensitiveActions.projectCommandAction(
139: "nbms", NbBundle.getMessage(SuiteActions.class,
140: "SUITE_ACTION_nbms"), null)); // #64426
141: actions.add(null);
142: }
143: actions.add(CommonProjectActions.setAsMainProjectAction());
144: actions.add(CommonProjectActions.openSubprojectsAction());
145: actions.add(CommonProjectActions.closeProjectAction());
146: actions.add(null);
147: actions.add(CommonProjectActions.renameProjectAction());
148: actions.add(CommonProjectActions.moveProjectAction());
149: actions.add(CommonProjectActions.deleteProjectAction());
150:
151: actions.add(null);
152: actions.add(SystemAction.get(FindAction.class));
153: Collection<? extends Object> res = Lookups.forPath(
154: "Projects/Actions").lookupAll(Object.class); // NOI18N
155: if (!res.isEmpty()) {
156: actions.add(null);
157: for (Object next : res) {
158: if (next instanceof Action) {
159: actions.add((Action) next);
160: } else if (next instanceof JSeparator) {
161: actions.add(null);
162: }
163: }
164: }
165: actions.add(null);
166: actions.add(CommonProjectActions.customizeProjectAction());
167: return actions.toArray(new Action[actions.size()]);
168: }
169:
170: private static void addFromLayers(List<Action> actions, String path) {
171: Lookup look = Lookups.forPath(path);
172: for (Object next : look.lookupAll(Object.class)) {
173: if (next instanceof Action) {
174: actions.add((Action) next);
175: } else if (next instanceof JSeparator) {
176: actions.add(null);
177: }
178: }
179: }
180:
181: private final SuiteProject project;
182:
183: public SuiteActions(SuiteProject project) {
184: this .project = project;
185: }
186:
187: public String[] getSupportedActions() {
188: List<String> actions = new ArrayList<String>(Arrays.asList(
189: ActionProvider.COMMAND_BUILD,
190: ActionProvider.COMMAND_CLEAN,
191: ActionProvider.COMMAND_REBUILD,
192: ActionProvider.COMMAND_RUN,
193: ActionProvider.COMMAND_DEBUG,
194: "build-zip", // NOI18N
195: "build-jnlp", // NOI18N
196: "run-jnlp", // NOI18N
197: "debug-jnlp", // NOI18N
198: "build-mac", // NOI18N
199: "nbms", // NOI18N
200: "profile", // NOI18N
201: ActionProvider.COMMAND_RENAME,
202: ActionProvider.COMMAND_MOVE,
203: ActionProvider.COMMAND_DELETE));
204: NbPlatform platform = project.getPlatform(true); //true -> #96095
205: if (platform != null
206: && platform.getHarnessVersion() >= NbPlatform.HARNESS_VERSION_61) {
207: actions.add(ActionProvider.COMMAND_TEST);
208: }
209: return actions.toArray(new String[actions.size()]);
210: }
211:
212: public boolean isActionEnabled(String command, Lookup context)
213: throws IllegalArgumentException {
214: if (ActionProvider.COMMAND_DELETE.equals(command)
215: || ActionProvider.COMMAND_RENAME.equals(command)
216: || ActionProvider.COMMAND_MOVE.equals(command)) {
217: return true;
218: } else if (Arrays.asList(getSupportedActions()).contains(
219: command)) {
220: return findBuildXml(project) != null;
221: } else {
222: throw new IllegalArgumentException(command);
223: }
224: }
225:
226: public void invokeAction(String command, Lookup context)
227: throws IllegalArgumentException {
228: if (ActionProvider.COMMAND_DELETE.equals(command)) {
229: DefaultProjectOperations
230: .performDefaultDeleteOperation(project);
231: } else if (ActionProvider.COMMAND_RENAME.equals(command)) {
232: DefaultProjectOperations.performDefaultRenameOperation(
233: project, null);
234: } else if (ActionProvider.COMMAND_MOVE.equals(command)) {
235: DefaultProjectOperations
236: .performDefaultMoveOperation(project);
237: } else {
238: NbPlatform plaf = project.getPlatform(false);
239: if (plaf != null) {
240: int v = plaf.getHarnessVersion();
241: if (v != NbPlatform.HARNESS_VERSION_UNKNOWN) {
242: for (Project p : project.getLookup().lookup(
243: SubprojectProvider.class).getSubprojects()) {
244: if (v < ((NbModuleProject) p)
245: .getMinimumHarnessVersion()) {
246: ModuleActions.promptForNewerHarness();
247: return;
248: }
249: }
250: }
251: }
252: try {
253: invokeActionImpl(command, context);
254: } catch (IOException e) {
255: Util.err.notify(e);
256: }
257: }
258: }
259:
260: /** Used from tests to start the build script and get task that allows to track its progress.
261: * @return null or task that was started
262: */
263: public ExecutorTask invokeActionImpl(String command, Lookup context)
264: throws IllegalArgumentException, IOException {
265: String[] targetNames;
266: if (command.equals(ActionProvider.COMMAND_BUILD)) {
267: targetNames = new String[] { "build" }; // NOI18N
268: } else if (command.equals(ActionProvider.COMMAND_CLEAN)) {
269: targetNames = new String[] { "clean" }; // NOI18N
270: } else if (command.equals(ActionProvider.COMMAND_REBUILD)) {
271: targetNames = new String[] { "clean", "build" }; // NOI18N
272: } else if (command.equals(ActionProvider.COMMAND_RUN)) {
273: targetNames = new String[] { "run" }; // NOI18N
274: } else if (command.equals(ActionProvider.COMMAND_DEBUG)) {
275: targetNames = new String[] { "debug" }; // NOI18N
276: } else if (command.equals(ActionProvider.COMMAND_TEST)) {
277: targetNames = new String[] { "test" }; // NOI18N
278: } else if (command.equals("build-zip")) { // NOI18N
279: if (promptForAppName(PROMPT_FOR_APP_NAME_MODE_ZIP)) { // #65006
280: return null;
281: }
282: targetNames = new String[] { "build-zip" }; // NOI18N
283: } else if (command.equals("build-jnlp")) { // NOI18N
284: if (promptForAppName(PROMPT_FOR_APP_NAME_MODE_JNLP)) {
285: return null;
286: }
287: targetNames = new String[] { "build-jnlp" }; // NOI18N
288: } else if (command.equals("run-jnlp")) { // NOI18N
289: if (promptForAppName(PROMPT_FOR_APP_NAME_MODE_JNLP)) {
290: return null;
291: }
292: targetNames = new String[] { "run-jnlp" }; // NOI18N
293: } else if (command.equals("debug-jnlp")) { // NOI18N
294: if (promptForAppName(PROMPT_FOR_APP_NAME_MODE_JNLP)) {
295: return null;
296: }
297: targetNames = new String[] { "debug-jnlp" }; // NOI18N
298: } else if (command.equals("build-mac")) { // NOI18N
299: targetNames = new String[] { "build-mac" }; // NOI18N
300: } else if (command.equals("nbms")) { // NOI18N
301: targetNames = new String[] { "nbms" }; // NOI18N
302: } else if (command.equals("profile")) { // NOI18N
303: targetNames = new String[] { "profile" }; // NOI18N
304: } else {
305: throw new IllegalArgumentException(command);
306: }
307:
308: return ActionUtils.runTarget(findBuildXml(project),
309: targetNames, null);
310: }
311:
312: private static FileObject findBuildXml(SuiteProject project) {
313: return project.getProjectDirectory().getFileObject(
314: GeneratedFilesHelper.BUILD_XML_PATH);
315: }
316:
317: private static final int PROMPT_FOR_APP_NAME_MODE_JNLP = 0;
318: private static final int PROMPT_FOR_APP_NAME_MODE_ZIP = 1;
319:
320: /** @return true if the dialog is shown */
321: private boolean promptForAppName(int mode) {
322: String name = project.getEvaluator().getProperty("app.name"); // NOI18N
323: if (name != null) {
324: return false;
325: }
326:
327: // #61372: warn the user, rather than disabling the action.
328: String msg;
329: switch (mode) {
330: case PROMPT_FOR_APP_NAME_MODE_JNLP:
331: msg = NbBundle.getMessage(ModuleActions.class,
332: "ERR_app_name_jnlp");
333: break;
334: case PROMPT_FOR_APP_NAME_MODE_ZIP:
335: msg = NbBundle.getMessage(ModuleActions.class,
336: "ERR_app_name_zip");
337: break;
338: default:
339: throw new AssertionError(mode);
340: }
341: if (UIUtil.showAcceptCancelDialog(NbBundle.getMessage(
342: ModuleActions.class, "TITLE_app_name"), msg, NbBundle
343: .getMessage(ModuleActions.class,
344: "LBL_configure_app_name"), NbBundle.getMessage(
345: ModuleActions.class, "ACSD_configure_app_name"), null,
346: NotifyDescriptor.WARNING_MESSAGE)) {
347: SuiteCustomizer cpi = project.getLookup().lookup(
348: SuiteCustomizer.class);
349: cpi
350: .showCustomizer(
351: SuiteCustomizer.APPLICATION,
352: SuiteCustomizer.APPLICATION_CREATE_STANDALONE_APPLICATION);
353: }
354: return true;
355: }
356:
357: }
|