| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.netbeans.modules.ant.debugger; |
| |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.io.IOException; |
| import java.text.Collator; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Set; |
| import java.util.SortedSet; |
| import java.util.TreeSet; |
| import javax.swing.AbstractAction; |
| import javax.swing.Action; |
| import javax.swing.JButton; |
| import javax.swing.JMenu; |
| import javax.swing.JMenuItem; |
| import javax.swing.JPopupMenu; |
| import org.apache.tools.ant.module.AntModule; |
| import org.apache.tools.ant.module.api.AntProjectCookie; |
| import org.apache.tools.ant.module.api.AntTargetExecutor; |
| import org.apache.tools.ant.module.api.support.TargetLister; |
| import org.openide.DialogDescriptor; |
| import org.openide.DialogDisplayer; |
| import org.openide.NotifyDescriptor; |
| import org.openide.awt.ActionID; |
| import org.openide.awt.ActionReference; |
| import org.openide.awt.ActionRegistration; |
| import org.openide.awt.Actions; |
| import org.openide.execution.ExecutorTask; |
| import org.openide.util.ContextAwareAction; |
| import org.openide.util.Lookup; |
| import org.openide.util.NbBundle; |
| import org.openide.util.RequestProcessor; |
| import org.openide.util.actions.Presenter; |
| |
| /** |
| * Submenu which permits the user to debug various targets from the project. |
| * Distinction made between the main target, other documented targets, and other |
| * undocumented targets. |
| */ |
| @ActionID(id = "org.netbeans.modules.ant.debugger.RunTargetsAction", category = "Build") |
| @ActionRegistration(displayName = "", lazy=false) |
| @ActionReference(path = "Loaders/text/x-ant+xml/Actions", position = 300) |
| @NbBundle.Messages("LBL_run_targets_action=Debug Target") |
| public final class RunTargetsAction extends AbstractAction implements ContextAwareAction { |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| assert false : "Action should never be called without a context"; |
| } |
| |
| @Override |
| public Action createContextAwareInstance(Lookup actionContext) { |
| return new ContextAction(actionContext); |
| } |
| |
| /** |
| * The particular instance of this action for a given project. |
| */ |
| private static final class ContextAction extends AbstractAction implements Presenter.Popup { |
| |
| private final AntProjectCookie project; |
| |
| public ContextAction(Lookup lkp) { |
| super(Bundle.LBL_run_targets_action()); |
| Collection<? extends AntProjectCookie> apcs = lkp.lookupAll(AntProjectCookie.class); |
| AntProjectCookie _project = null; |
| if (apcs.size() == 1) { |
| _project = apcs.iterator().next(); |
| if (_project.getParseException() != null) { |
| _project = null; |
| } |
| } |
| project = _project; |
| super.setEnabled(project != null); |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| assert false : "Action should not be called directly"; |
| } |
| |
| @Override |
| public JMenuItem getPopupPresenter() { |
| if (project != null) { |
| return createMenu(project); |
| } else { |
| return new Actions.MenuItem(this, false); |
| } |
| } |
| |
| @Override |
| public void setEnabled(boolean b) { |
| assert false : "No modifications to enablement status permitted"; |
| } |
| |
| } |
| |
| /** |
| * Create the sub-menu. |
| */ |
| private static JMenu createMenu(AntProjectCookie project) { |
| return new LazyMenu(project); |
| } |
| |
| private static final class LazyMenu extends JMenu { |
| |
| private final AntProjectCookie project; |
| private boolean initialized = false; |
| |
| public LazyMenu(AntProjectCookie project) { |
| super(Bundle.LBL_run_targets_action()); |
| this.project = project; |
| } |
| |
| @Override |
| public JPopupMenu getPopupMenu() { |
| if (!initialized) { |
| initialized = true; |
| Set<TargetLister.Target> allTargets; |
| try { |
| allTargets = TargetLister.getTargets(project); |
| } catch (IOException e) { |
| DialogDisplayer.getDefault().notify( |
| new NotifyDescriptor.Message(e.getLocalizedMessage())); |
| allTargets = Collections.emptySet(); |
| } |
| String defaultTarget = null; |
| SortedSet<String> describedTargets = new TreeSet<>(Collator.getInstance()); |
| SortedSet<String> otherTargets = new TreeSet<>(Collator.getInstance()); |
| for (TargetLister.Target t : allTargets) { |
| if (t.isOverridden()) { |
| // Cannot be called. |
| continue; |
| } |
| if (t.isInternal()) { |
| // Don't present in GUI. |
| continue; |
| } |
| String name = t.getName(); |
| if (t.isDefault()) { |
| defaultTarget = name; |
| } else if (t.isDescribed()) { |
| describedTargets.add(name); |
| } else { |
| otherTargets.add(name); |
| } |
| } |
| boolean needsep = false; |
| VerticalGridLayout vgl = new VerticalGridLayout(); |
| getPopupMenu().setLayout(vgl); |
| if (defaultTarget != null) { |
| needsep = true; |
| JMenuItem menuitem = new JMenuItem(defaultTarget); |
| menuitem.addActionListener(new TargetMenuItemHandler(project, defaultTarget)); |
| add(menuitem); |
| } |
| if (needsep) { |
| needsep = false; |
| addSeparator(); |
| } |
| if (!describedTargets.isEmpty()) { |
| needsep = true; |
| for (String target : describedTargets) { |
| JMenuItem menuitem = new JMenuItem(target); |
| menuitem.addActionListener(new TargetMenuItemHandler(project, target)); |
| add(menuitem); |
| } |
| } |
| if (needsep) { |
| needsep = false; |
| addSeparator(); |
| } |
| if (!otherTargets.isEmpty()) { |
| needsep = true; |
| JMenu submenu = new JMenu(NbBundle.getMessage(RunTargetsAction.class, "LBL_run_other_targets")); |
| VerticalGridLayout submenuVgl = new VerticalGridLayout(); |
| submenu.getPopupMenu().setLayout(submenuVgl); |
| for (String target : otherTargets) { |
| JMenuItem menuitem = new JMenuItem(target); |
| menuitem.addActionListener(new TargetMenuItemHandler(project, target)); |
| submenu.add(menuitem); |
| } |
| add(submenu); |
| } |
| if (needsep) { |
| needsep = false; |
| addSeparator(); |
| } |
| add(new AdvancedAction(project, allTargets)); |
| } |
| return super.getPopupMenu(); |
| } |
| |
| } |
| |
| /** |
| * Action handler for a menu item representing one target. |
| */ |
| static final class TargetMenuItemHandler implements ActionListener, Runnable { |
| |
| private final AntProjectCookie project; |
| private final String target; |
| |
| public TargetMenuItemHandler(AntProjectCookie project, String target) { |
| this.project = project; |
| this.target = target; |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent ev) { |
| // #16720 part 2: don't do this in the event thread... |
| RequestProcessor.getDefault().post(this); |
| } |
| |
| @Override |
| public void run() { |
| try { |
| DebuggerAntLogger.getDefault ().debugFile (project.getFile ()); |
| AntTargetExecutor.Env env = new AntTargetExecutor.Env (); |
| AntTargetExecutor executor = AntTargetExecutor.createTargetExecutor |
| (env); |
| ExecutorTask executorTask = executor.execute |
| (project, new String[] {target}); |
| DebuggerAntLogger.getDefault().fileExecutor(project.getFile(), executorTask); |
| } catch (IOException ioe) { |
| AntModule.err.notify(ioe); |
| } |
| } |
| |
| } |
| |
| /** |
| * Menu item to let the user select a random target(s), and set properties and verbosity. |
| */ |
| private static final class AdvancedAction extends AbstractAction { |
| |
| private final AntProjectCookie project; |
| private final Set<TargetLister.Target> allTargets; |
| |
| public AdvancedAction(AntProjectCookie project, Set/*<TargetLister.Target>*/ allTargets) { |
| super(NbBundle.getMessage(RunTargetsAction.class, "LBL_run_advanced")); |
| this.project = project; |
| this.allTargets = allTargets; |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| String title = NbBundle.getMessage(RunTargetsAction.class, "TITLE_run_advanced"); |
| AdvancedActionPanel panel = new AdvancedActionPanel(project, allTargets); |
| DialogDescriptor dd = new DialogDescriptor(panel, title); |
| dd.setOptionType(NotifyDescriptor.OK_CANCEL_OPTION); |
| JButton run = new JButton(NbBundle.getMessage(RunTargetsAction.class, "LBL_run_advanced_run")); |
| run.setDefaultCapable(true); |
| JButton cancel = new JButton(NbBundle.getMessage(RunTargetsAction.class, "LBL_run_advanced_cancel")); |
| dd.setOptions(new Object[] {run, cancel}); |
| dd.setModal(true); |
| Object result = DialogDisplayer.getDefault().notify(dd); |
| if (result.equals(run)) { |
| try { |
| panel.run(); |
| } catch (IOException x) { |
| AntModule.err.notify(x); |
| } |
| } |
| } |
| |
| } |
| |
| } |