SelectToolTask.java revision 3827:44bdefe64114
152284Sobrien/*
2169689Skan * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
352284Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
452284Sobrien *
552284Sobrien * This code is free software; you can redistribute it and/or modify it
652284Sobrien * under the terms of the GNU General Public License version 2 only, as
752284Sobrien * published by the Free Software Foundation.  Oracle designates this
852284Sobrien * particular file as subject to the "Classpath" exception as provided
952284Sobrien * by Oracle in the LICENSE file that accompanied this code.
1052284Sobrien *
1152284Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
1252284Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1352284Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1452284Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1552284Sobrien * accompanied this code).
16169689Skan *
17169689Skan * You should have received a copy of the GNU General Public License version
1852284Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
1990075Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2090075Sobrien *
2190075Sobrien * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2252284Sobrien * or visit www.oracle.com if you need additional information or have any
2352284Sobrien * questions.
2452284Sobrien */
2552284Sobrien
2652284Sobrienpackage anttasks;
2752284Sobrien
2852284Sobrienimport java.awt.GridBagConstraints;
2952284Sobrienimport java.awt.GridBagLayout;
3052284Sobrienimport java.awt.event.ActionEvent;
31132718Skanimport java.awt.event.ActionListener;
32132718Skanimport java.awt.event.FocusEvent;
33132718Skanimport java.awt.event.FocusListener;
3452284Sobrienimport java.awt.event.ItemEvent;
3590075Sobrienimport java.awt.event.ItemListener;
3690075Sobrienimport java.io.BufferedReader;
3752284Sobrienimport java.io.BufferedWriter;
3890075Sobrienimport java.io.File;
3952284Sobrienimport java.io.FileReader;
4090075Sobrienimport java.io.FileWriter;
4152284Sobrienimport java.io.IOException;
4290075Sobrienimport java.io.Reader;
43132718Skanimport java.io.Writer;
4452284Sobrienimport java.util.EnumSet;
4552284Sobrienimport java.util.Properties;
4652284Sobrien
4752284Sobrienimport javax.swing.JButton;
4852284Sobrienimport javax.swing.JCheckBox;
4952284Sobrienimport javax.swing.JComboBox;
5052284Sobrienimport javax.swing.JDialog;
51132718Skanimport javax.swing.JLabel;
5252284Sobrienimport javax.swing.JOptionPane;
5390075Sobrienimport javax.swing.JPanel;
54169689Skanimport javax.swing.JTextField;
55169689Skan
56169689Skanimport javax.swing.SwingUtilities;
57169689Skan
58169689Skanimport org.apache.tools.ant.BuildException;
59169689Skanimport org.apache.tools.ant.Project;
60169689Skanimport org.apache.tools.ant.Task;
6190075Sobrien
62/**
63 * Task to allow the user to control langtools tools built when using NetBeans.
64 *
65 * There are two primary modes.
66 * 1) Property mode. In this mode, property names are provided to get values
67 * that may be specified by the user, either directly in a GUI dialog, or
68 * read from a properties file. If the GUI dialog is invoked, values may
69 * optionally be set for future use.
70 * 2) Setup mode. In this mode, no property names are provided, and the GUI
71 * is invoked to allow the user to set or reset values for use in property mode.
72 */
73public class SelectToolTask extends Task {
74
75    enum ToolChoices {
76        NONE(""),
77        JAVAC("javac"),
78        JAVADOC("javadoc"),
79        JAVAH("javah"),
80        JAVAP("javap"),
81        JSHELL("jshell");
82
83        String toolName;
84        boolean bootstrap;
85
86        ToolChoices(String toolName) {
87            this(toolName, false);
88        }
89
90        ToolChoices(String toolName, boolean bootstrap) {
91            this.toolName = toolName;
92            this.bootstrap = bootstrap;
93        }
94
95        @Override
96        public String toString() {
97            return toolName;
98        }
99    }
100
101    /**
102     * Set the location of the private properties file used to keep the retain
103     * user preferences for this repository.
104     * @param propertyFile the private properties file
105     */
106    public void setPropertyFile(File propertyFile) {
107        this.propertyFile = propertyFile;
108    }
109
110    /**
111     * Set the name of the property which will be set to the name of the
112     * selected tool, if any. If no tool is selected, the property will
113     * remain unset.
114     * @param toolProperty the tool name property
115     */
116    public void setToolProperty(String toolProperty) {
117        this.toolProperty = toolProperty;
118    }
119
120    /**
121     * Set the name of the property which will be set to the execution args of the
122     * selected tool, if any. The args default to an empty string.
123     * @param argsProperty the execution args property value
124     */
125    public void setArgsProperty(String argsProperty) {
126        this.argsProperty = argsProperty;
127    }
128
129    /**
130     * Specify whether or not to pop up a dialog if the user has not specified
131     * a default value for a property.
132     * @param askIfUnset a boolean flag indicating to prompt the user or not
133     */
134    public void setAskIfUnset(boolean askIfUnset) {
135        this.askIfUnset = askIfUnset;
136    }
137
138    @Override
139    public void execute() {
140        Project p = getProject();
141
142        Properties props = readProperties(propertyFile);
143        toolName = props.getProperty("tool.name");
144        if (toolName != null) {
145            toolArgs = props.getProperty(toolName + ".args", "");
146        }
147
148        if (toolProperty == null ||
149            askIfUnset && (toolName == null
150                || (argsProperty != null && toolArgs == null))) {
151            showGUI(props);
152        }
153
154        // finally, return required values, if any
155        if (toolProperty != null && !(toolName == null || toolName.equals(""))) {
156            p.setProperty(toolProperty, toolName);
157
158            if (argsProperty != null && toolArgs != null)
159                p.setProperty(argsProperty, toolArgs);
160        }
161    }
162
163    void showGUI(Properties fileProps) {
164        Properties guiProps = new Properties(fileProps);
165        JOptionPane p = createPane(guiProps);
166        p.createDialog("Select Tool").setVisible(true);
167
168        ToolChoices tool = (ToolChoices)toolChoice.getSelectedItem();
169
170        toolName = tool.toolName;
171        toolArgs = argsField.getText();
172        if (defaultCheck.isSelected()) {
173            if (toolName.equals("")) {
174                fileProps.remove("tool.name");
175                fileProps.remove("tool.bootstrap");
176            } else {
177                fileProps.remove("tool.bootstrap");
178                fileProps.put("tool.name", toolName);
179                fileProps.put(toolName + ".args", toolArgs);
180            }
181            writeProperties(propertyFile, fileProps);
182        }
183    }
184
185    JOptionPane createPane(final Properties props) {
186        JPanel body = new JPanel(new GridBagLayout());
187        GridBagConstraints lc = new GridBagConstraints();
188        lc.insets.right = 10;
189        lc.insets.bottom = 3;
190        GridBagConstraints fc = new GridBagConstraints();
191        fc.gridx = 1;
192        fc.gridwidth = GridBagConstraints.NONE;
193        fc.insets.bottom = 3;
194
195        JPanel toolPane = new JPanel(new GridBagLayout());
196
197        JLabel toolLabel = new JLabel("Tool:");
198        body.add(toolLabel, lc);
199        EnumSet<ToolChoices> toolChoices = toolProperty == null ?
200                EnumSet.allOf(ToolChoices.class) : EnumSet.range(ToolChoices.JAVAC, ToolChoices.JAVAP);
201        toolChoice = new JComboBox<>(toolChoices.toArray());
202        ToolChoices tool = toolName != null ? ToolChoices.valueOf(toolName.toUpperCase()) : null;
203        if (toolName != null) {
204            toolChoice.setSelectedItem(tool);
205        }
206        toolChoice.addItemListener(e -> {
207            ToolChoices tool1 = (ToolChoices)e.getItem();
208            argsField.setText(getDefaultArgsForTool(props, tool1));
209            if (toolProperty != null)
210                okButton.setEnabled(tool1 != ToolChoices.NONE);
211        });
212        fc.anchor = GridBagConstraints.EAST;
213
214        GridBagConstraints toolConstraint = new GridBagConstraints();
215        fc.anchor = GridBagConstraints.WEST;
216
217        toolPane.add(toolChoice, toolConstraint);
218
219        body.add(toolPane, fc);
220
221        argsField = new JTextField(getDefaultArgsForTool(props, tool), 40);
222        if (toolProperty == null || argsProperty != null) {
223            JLabel argsLabel = new JLabel("Args:");
224            body.add(argsLabel, lc);
225            body.add(argsField, fc);
226            argsField.addFocusListener(new FocusListener() {
227                @Override
228                public void focusGained(FocusEvent e) {
229                }
230                @Override
231                public void focusLost(FocusEvent e) {
232                    String toolName = ((ToolChoices)toolChoice.getSelectedItem()).toolName;
233                    if (toolName.length() > 0)
234                        props.put(toolName + ".args", argsField.getText());
235                }
236            });
237        }
238
239        defaultCheck = new JCheckBox("Set as default");
240        if (toolProperty == null)
241            defaultCheck.setSelected(true);
242        else
243            body.add(defaultCheck, fc);
244
245        final JOptionPane p = new JOptionPane(body);
246        okButton = new JButton("OK");
247        okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals("")));
248        okButton.addActionListener(e -> {
249            JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p);
250            d.setVisible(false);
251        });
252        p.setOptions(new Object[] { okButton });
253
254        return p;
255    }
256
257    Properties readProperties(File file) {
258        Properties p = new Properties();
259        if (file != null && file.exists()) {
260            Reader in = null;
261            try {
262                in = new BufferedReader(new FileReader(file));
263                p.load(in);
264                in.close();
265            } catch (IOException e) {
266                throw new BuildException("error reading property file", e);
267            } finally {
268                if (in != null) {
269                    try {
270                        in.close();
271                    } catch (IOException e) {
272                        throw new BuildException("cannot close property file", e);
273                    }
274                }
275            }
276        }
277        return p;
278    }
279
280    void writeProperties(File file, Properties p) {
281        if (file != null) {
282            Writer out = null;
283            try {
284                File dir = file.getParentFile();
285                if (dir != null && !dir.exists())
286                    dir.mkdirs();
287                out = new BufferedWriter(new FileWriter(file));
288                p.store(out, "langtools properties");
289                out.close();
290            } catch (IOException e) {
291                throw new BuildException("error writing property file", e);
292            } finally {
293                if (out != null) {
294                    try {
295                        out.close();
296                    } catch (IOException e) {
297                        throw new BuildException("cannot close property file", e);
298                    }
299                }
300            }
301        }
302    }
303
304    String getDefaultArgsForTool(Properties props, ToolChoices tool) {
305        if (tool == null)
306            return "";
307        String toolName = tool.toolName;
308        return toolName.equals("") ? "" : props.getProperty(toolName + ".args", "");
309    }
310
311    // Ant task parameters
312    private boolean askIfUnset;
313    private String toolProperty;
314    private String argsProperty;
315    private File propertyFile;
316
317    // GUI components
318    private JComboBox<?> toolChoice;
319    private JTextField argsField;
320    private JCheckBox defaultCheck;
321    private JButton okButton;
322
323    // Result values for the client
324    private String toolName;
325    private String toolArgs;
326}
327