SelectToolTask.java revision 2020:d87f017ec217
1114902Sscottl/*
2114902Sscottl * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
3114902Sscottl * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4114902Sscottl *
5114902Sscottl * This code is free software; you can redistribute it and/or modify it
6114902Sscottl * under the terms of the GNU General Public License version 2 only, as
7114902Sscottl * published by the Free Software Foundation.  Oracle designates this
8114902Sscottl * particular file as subject to the "Classpath" exception as provided
9239462Sdim * by Oracle in the LICENSE file that accompanied this code.
10239462Sdim *
11239462Sdim * This code is distributed in the hope that it will be useful, but WITHOUT
12239462Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package anttasks;
27
28import java.awt.GridBagConstraints;
29import java.awt.GridBagLayout;
30import java.awt.event.ActionEvent;
31import java.awt.event.ActionListener;
32import java.awt.event.FocusEvent;
33import java.awt.event.FocusListener;
34import java.awt.event.ItemEvent;
35import java.awt.event.ItemListener;
36import java.io.BufferedReader;
37import java.io.BufferedWriter;
38import java.io.File;
39import java.io.FileReader;
40import java.io.FileWriter;
41import java.io.IOException;
42import java.io.Reader;
43import java.io.Writer;
44import java.util.ArrayList;
45import java.util.Arrays;
46import java.util.EnumSet;
47import java.util.List;
48import java.util.Properties;
49import javax.swing.JButton;
50import javax.swing.JCheckBox;
51import javax.swing.JComboBox;
52import javax.swing.JDialog;
53import javax.swing.JLabel;
54import javax.swing.JOptionPane;
55import javax.swing.JPanel;
56import javax.swing.JTextField;
57
58import javax.swing.SwingUtilities;
59import org.apache.tools.ant.BuildException;
60import org.apache.tools.ant.Project;
61import org.apache.tools.ant.Task;
62
63/**
64 * Task to allow the user to control langtools tools built when using NetBeans.
65 *
66 * There are two primary modes.
67 * 1) Property mode. In this mode, property names are provided to get values
68 * that may be specified by the user, either directly in a GUI dialog, or
69 * read from a properties file. If the GUI dialog is invoked, values may
70 * optionally be set for future use.
71 * 2) Setup mode. In this mode, no property names are provided, and the GUI
72 * is invoked to allow the user to set or reset values for use in property mode.
73 */
74public class SelectToolTask extends Task {
75
76    enum ToolChoices {
77        NONE(""),
78        JAVAC("javac"),
79        JAVADOC("javadoc"),
80        JAVAH("javah"),
81        JAVAP("javap");
82
83        String toolName;
84        boolean bootstrap;
85
86        ToolChoices(String toolName) {
87            this(toolName, false);
88        }
89
90        ToolChoices(String toolName, boolean boostrap) {
91            this.toolName = toolName;
92        }
93
94        @Override
95        public String toString() {
96            return toolName;
97        }
98    }
99
100    /**
101     * Set the location of the private properties file used to keep the retain
102     * user preferences for this repository.
103     */
104    public void setPropertyFile(File propertyFile) {
105        this.propertyFile = propertyFile;
106    }
107
108    /**
109     * Set the name of the property which will be set to the name of the
110     * selected tool, if any. If no tool is selected, the property will
111     * remain unset.
112     */
113    public void setToolProperty(String toolProperty) {
114        this.toolProperty = toolProperty;
115    }
116
117    /**
118     * Set the name of the property which will be set to the execution args of the
119     * selected tool, if any. The args default to an empty string.
120     */
121    public void setArgsProperty(String argsProperty) {
122        this.argsProperty = argsProperty;
123    }
124
125    /**
126     * Set the name of the property which will be set to the execution args of the
127     * selected tool, if any. The args default to an empty string.
128     */
129    public void setBootstrapProperty(String bootstrapProperty) {
130        this.bootstrapProperty = bootstrapProperty;
131    }
132
133    /**
134     * Specify whether or not to pop up a dialog if the user has not specified
135     * a default value for a property.
136     */
137    public void setAskIfUnset(boolean askIfUnset) {
138        this.askIfUnset = askIfUnset;
139    }
140
141    @Override
142    public void execute() {
143        Project p = getProject();
144
145        Properties props = readProperties(propertyFile);
146        toolName = props.getProperty("tool.name");
147        toolBootstrap = props.getProperty("tool.bootstrap") != null;
148        if (toolName != null) {
149            toolArgs = props.getProperty(toolName + ".args", "");
150        }
151
152        if (toolProperty == null ||
153            askIfUnset && (toolName == null
154                || (argsProperty != null && toolArgs == null))) {
155            showGUI(props);
156        }
157
158        // finally, return required values, if any
159        if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
160            p.setProperty(toolProperty, toolName);
161            if (toolBootstrap)
162                p.setProperty(bootstrapProperty, "true");
163
164            if (argsProperty != null && toolArgs != null)
165                p.setProperty(argsProperty, toolArgs);
166        }
167    }
168
169    void showGUI(Properties fileProps) {
170        Properties guiProps = new Properties(fileProps);
171        JOptionPane p = createPane(guiProps);
172        p.createDialog("Select Tool").setVisible(true);
173
174        toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
175        toolArgs = argsField.getText();
176        toolBootstrap = bootstrapCheckbox.isSelected();
177        if (defaultCheck.isSelected()) {
178            if (toolName.equals("")) {
179                fileProps.remove("tool.name");
180                fileProps.remove("tool.bootstrap");
181            } else {
182                fileProps.put("tool.name", toolName);
183                if (toolBootstrap) {
184                    fileProps.put("tool.bootstrap", "true");
185                } else {
186                    fileProps.remove("tool.bootstrap");
187                }
188                fileProps.put(toolName + ".args", toolArgs);
189            }
190            writeProperties(propertyFile, fileProps);
191        }
192    }
193
194    JOptionPane createPane(final Properties props) {
195        JPanel body = new JPanel(new GridBagLayout());
196        GridBagConstraints lc = new GridBagConstraints();
197        lc.insets.right = 10;
198        lc.insets.bottom = 3;
199        GridBagConstraints fc = new GridBagConstraints();
200        fc.gridx = 1;
201        fc.gridwidth = GridBagConstraints.NONE;
202        fc.insets.bottom = 3;
203
204        JPanel toolPane = new JPanel(new GridBagLayout());
205
206        JLabel toolLabel = new JLabel("Tool:");
207        body.add(toolLabel, lc);
208        EnumSet<ToolChoices> toolChoices = toolProperty == null ?
209                EnumSet.allOf(ToolChoices.class) : EnumSet.range(ToolChoices.JAVAC, ToolChoices.JAVAP);
210        toolChoice = new JComboBox(toolChoices.toArray());
211        if (toolName != null)
212            toolChoice.setSelectedItem(ToolChoices.valueOf(toolName.toUpperCase()));
213        toolChoice.addItemListener(new ItemListener() {
214            public void itemStateChanged(ItemEvent e) {
215                String tn = ((ToolChoices)e.getItem()).toolName;
216                argsField.setText(getDefaultArgsForTool(props, tn));
217                if (toolProperty != null)
218                    okButton.setEnabled(!tn.equals(""));
219            }
220        });
221        GridBagConstraints checkConstraint = new GridBagConstraints();
222        fc.anchor = GridBagConstraints.EAST;
223
224        GridBagConstraints toolConstraint = new GridBagConstraints();
225        fc.anchor = GridBagConstraints.WEST;
226
227        toolPane.add(toolChoice, toolConstraint);
228        bootstrapCheckbox = new JCheckBox("bootstrap", toolBootstrap);
229        toolPane.add(bootstrapCheckbox, checkConstraint);
230
231        body.add(toolPane, fc);
232
233        argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40);
234        if (toolProperty == null || argsProperty != null) {
235            JLabel argsLabel = new JLabel("Args:");
236            body.add(argsLabel, lc);
237            body.add(argsField, fc);
238            argsField.addFocusListener(new FocusListener() {
239                public void focusGained(FocusEvent e) {
240                }
241                public void focusLost(FocusEvent e) {
242                    String toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
243                    if (toolName.length() > 0)
244                        props.put(toolName + ".args", argsField.getText());
245                }
246            });
247        }
248
249        defaultCheck = new JCheckBox("Set as default");
250        if (toolProperty == null)
251            defaultCheck.setSelected(true);
252        else
253            body.add(defaultCheck, fc);
254
255        final JOptionPane p = new JOptionPane(body);
256        okButton = new JButton("OK");
257        okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals("")));
258        okButton.addActionListener(new ActionListener() {
259            public void actionPerformed(ActionEvent e) {
260                JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p);
261                d.setVisible(false);
262            }
263        });
264        p.setOptions(new Object[] { okButton });
265
266        return p;
267    }
268
269    Properties readProperties(File file) {
270        Properties p = new Properties();
271        if (file != null && file.exists()) {
272            Reader in = null;
273            try {
274                in = new BufferedReader(new FileReader(file));
275                p.load(in);
276                in.close();
277            } catch (IOException e) {
278                throw new BuildException("error reading property file", e);
279            } finally {
280                if (in != null) {
281                    try {
282                        in.close();
283                    } catch (IOException e) {
284                        throw new BuildException("cannot close property file", e);
285                    }
286                }
287            }
288        }
289        return p;
290    }
291
292    void writeProperties(File file, Properties p) {
293        if (file != null) {
294            Writer out = null;
295            try {
296                File dir = file.getParentFile();
297                if (dir != null && !dir.exists())
298                    dir.mkdirs();
299                out = new BufferedWriter(new FileWriter(file));
300                p.store(out, "langtools properties");
301                out.close();
302            } catch (IOException e) {
303                throw new BuildException("error writing property file", e);
304            } finally {
305                if (out != null) {
306                    try {
307                        out.close();
308                    } catch (IOException e) {
309                        throw new BuildException("cannot close property file", e);
310                    }
311                }
312            }
313        }
314    }
315
316    String getDefaultArgsForTool(Properties props, String tn) {
317        return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", "");
318    }
319
320    // Ant task parameters
321    private boolean askIfUnset;
322    private String toolProperty;
323    private String bootstrapProperty;
324    private String argsProperty;
325    private File propertyFile;
326
327    // GUI components
328    private JComboBox toolChoice;
329    private JCheckBox bootstrapCheckbox;
330    private JTextField argsField;
331    private JCheckBox defaultCheck;
332    private JButton okButton;
333
334    // Result values for the client
335    private String toolName;
336    private boolean toolBootstrap;
337    private String toolArgs;
338}
339