jjg@201: /* jjg@201: * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. jjg@201: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jjg@201: * jjg@201: * This code is free software; you can redistribute it and/or modify it jjg@201: * under the terms of the GNU General Public License version 2 only, as jjg@201: * published by the Free Software Foundation. Sun designates this jjg@201: * particular file as subject to the "Classpath" exception as provided jjg@201: * by Sun in the LICENSE file that accompanied this code. jjg@201: * jjg@201: * This code is distributed in the hope that it will be useful, but WITHOUT jjg@201: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jjg@201: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jjg@201: * version 2 for more details (a copy is included in the LICENSE file that jjg@201: * accompanied this code). jjg@201: * jjg@201: * You should have received a copy of the GNU General Public License version jjg@201: * 2 along with this work; if not, write to the Free Software Foundation, jjg@201: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jjg@201: * jjg@201: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, jjg@201: * CA 95054 USA or visit www.sun.com if you need additional information or jjg@201: * have any questions. jjg@201: */ jjg@201: jjg@201: import java.awt.GridBagConstraints; jjg@201: import java.awt.GridBagLayout; jjg@201: import java.awt.event.ActionEvent; jjg@201: import java.awt.event.ActionListener; jjg@201: import java.awt.event.FocusEvent; jjg@201: import java.awt.event.FocusListener; jjg@201: import java.awt.event.ItemEvent; jjg@201: import java.awt.event.ItemListener; jjg@201: import java.io.BufferedReader; jjg@201: import java.io.BufferedWriter; jjg@201: import java.io.File; jjg@201: import java.io.FileReader; jjg@201: import java.io.FileWriter; jjg@201: import java.io.IOException; jjg@201: import java.io.Reader; jjg@201: import java.io.Writer; jjg@201: import java.util.ArrayList; jjg@201: import java.util.Arrays; jjg@201: import java.util.List; jjg@201: import java.util.Properties; jjg@201: import javax.swing.JButton; jjg@201: import javax.swing.JCheckBox; jjg@201: import javax.swing.JComboBox; jjg@201: import javax.swing.JDialog; jjg@201: import javax.swing.JLabel; jjg@201: import javax.swing.JOptionPane; jjg@201: import javax.swing.JPanel; jjg@201: import javax.swing.JTextField; jjg@201: jjg@201: import javax.swing.SwingUtilities; jjg@201: import org.apache.tools.ant.BuildException; jjg@201: import org.apache.tools.ant.Project; jjg@201: import org.apache.tools.ant.Task; jjg@201: jjg@201: /** jjg@201: * Task to allow the user to control langtools tools built when using NetBeans. jjg@201: * jjg@201: * There are two primary modes. jjg@201: * 1) Property mode. In this mode, property names are provided to get values jjg@201: * that may be specified by the user, either directly in a GUI dialog, or jjg@201: * read from a properties file. If the GUI dialog is invoked, values may jjg@201: * optionally be set for future use. jjg@201: * 2) Setup mode. In this mode, no property names are provided, and the GUI jjg@201: * is invoked to allow the user to set or reset values for use in property mode. jjg@201: */ jjg@201: public class SelectToolTask extends Task { jjg@201: /** jjg@201: * Set the location of the private properties file used to keep the retain jjg@201: * user preferences for this repository. jjg@201: */ jjg@201: public void setPropertyFile(File propertyFile) { jjg@201: this.propertyFile = propertyFile; jjg@201: } jjg@201: jjg@201: /** jjg@201: * Set the name of the property which will be set to the name of the jjg@201: * selected tool, if any. If no tool is selected, the property will jjg@201: * remain unset. jjg@201: */ jjg@201: public void setToolProperty(String toolProperty) { jjg@201: this.toolProperty = toolProperty; jjg@201: } jjg@201: jjg@201: /** jjg@201: * Set the name of the property which will be set to the execution args of the jjg@201: * selected tool, if any. The args default to an empty string. jjg@201: */ jjg@201: public void setArgsProperty(String argsProperty) { jjg@201: this.argsProperty = argsProperty; jjg@201: } jjg@201: jjg@201: /** jjg@201: * Specify whether or not to pop up a dialog if the user has not specified jjg@201: * a default value for a property. jjg@201: */ jjg@201: public void setAskIfUnset(boolean askIfUnset) { jjg@201: this.askIfUnset = askIfUnset; jjg@201: } jjg@201: jjg@201: @Override jjg@201: public void execute() { jjg@201: Project p = getProject(); jjg@201: jjg@201: Properties props = readProperties(propertyFile); jjg@201: toolName = props.getProperty("tool.name"); jjg@201: if (toolName != null) { jjg@201: toolArgs = props.getProperty(toolName + ".args", ""); jjg@201: } jjg@201: jjg@201: if (toolProperty == null || jjg@201: askIfUnset && (toolName == null jjg@201: || (argsProperty != null && toolArgs == null))) { jjg@201: showGUI(props); jjg@201: } jjg@201: jjg@201: // finally, return required values, if any jjg@201: if (toolProperty != null && !(toolName == null || toolName.equals(""))) { jjg@201: p.setProperty(toolProperty, toolName); jjg@201: jjg@201: if (argsProperty != null && toolArgs != null) jjg@201: p.setProperty(argsProperty, toolArgs); jjg@201: } jjg@201: } jjg@201: jjg@201: void showGUI(Properties fileProps) { jjg@201: Properties guiProps = new Properties(fileProps); jjg@201: JOptionPane p = createPane(guiProps); jjg@201: p.createDialog("Select Tool").setVisible(true); jjg@201: jjg@201: toolName = (String) toolChoice.getSelectedItem(); jjg@201: toolArgs = argsField.getText(); jjg@201: jjg@201: if (defaultCheck.isSelected()) { jjg@201: if (toolName.equals("")) { jjg@201: fileProps.remove("tool.name"); jjg@201: } else { jjg@201: fileProps.put("tool.name", toolName); jjg@201: fileProps.put(toolName + ".args", toolArgs); jjg@201: } jjg@201: writeProperties(propertyFile, fileProps); jjg@201: } jjg@201: } jjg@201: jjg@201: JOptionPane createPane(final Properties props) { jjg@201: JPanel body = new JPanel(new GridBagLayout()); jjg@201: GridBagConstraints lc = new GridBagConstraints(); jjg@201: lc.insets.right = 10; jjg@201: lc.insets.bottom = 3; jjg@201: GridBagConstraints fc = new GridBagConstraints(); jjg@201: fc.anchor = GridBagConstraints.WEST; jjg@201: fc.gridx = 1; jjg@201: fc.gridwidth = GridBagConstraints.REMAINDER; jjg@201: fc.insets.bottom = 3; jjg@201: jjg@201: JLabel toolLabel = new JLabel("Tool:"); jjg@201: body.add(toolLabel, lc); jjg@201: String[] toolChoices = { "apt", "javac", "javadoc", "javah", "javap" }; jjg@201: if (true || toolProperty == null) { jjg@201: // include empty value in setup mode jjg@201: List l = new ArrayList(Arrays.asList(toolChoices)); jjg@201: l.add(0, ""); jjg@201: toolChoices = l.toArray(new String[l.size()]); jjg@201: } jjg@201: toolChoice = new JComboBox(toolChoices); jjg@201: if (toolName != null) jjg@201: toolChoice.setSelectedItem(toolName); jjg@201: toolChoice.addItemListener(new ItemListener() { jjg@201: public void itemStateChanged(ItemEvent e) { jjg@201: String tn = (String) e.getItem(); jjg@201: argsField.setText(getDefaultArgsForTool(props, tn)); jjg@201: if (toolProperty != null) jjg@201: okButton.setEnabled(!tn.equals("")); jjg@201: } jjg@201: }); jjg@201: body.add(toolChoice, fc); jjg@201: jjg@201: argsField = new JTextField(getDefaultArgsForTool(props, toolName), 40); jjg@201: if (toolProperty == null || argsProperty != null) { jjg@201: JLabel argsLabel = new JLabel("Args:"); jjg@201: body.add(argsLabel, lc); jjg@201: body.add(argsField, fc); jjg@201: argsField.addFocusListener(new FocusListener() { jjg@201: public void focusGained(FocusEvent e) { jjg@201: } jjg@201: public void focusLost(FocusEvent e) { jjg@201: String toolName = (String) toolChoice.getSelectedItem(); jjg@201: if (toolName.length() > 0) jjg@201: props.put(toolName + ".args", argsField.getText()); jjg@201: } jjg@201: }); jjg@201: } jjg@201: jjg@201: defaultCheck = new JCheckBox("Set as default"); jjg@201: if (toolProperty == null) jjg@201: defaultCheck.setSelected(true); jjg@201: else jjg@201: body.add(defaultCheck, fc); jjg@201: jjg@201: final JOptionPane p = new JOptionPane(body); jjg@201: okButton = new JButton("OK"); jjg@201: okButton.setEnabled(toolProperty == null || (toolName != null && !toolName.equals(""))); jjg@201: okButton.addActionListener(new ActionListener() { jjg@201: public void actionPerformed(ActionEvent e) { jjg@201: JDialog d = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, p); jjg@201: d.setVisible(false); jjg@201: } jjg@201: }); jjg@201: p.setOptions(new Object[] { okButton }); jjg@201: jjg@201: return p; jjg@201: } jjg@201: jjg@201: Properties readProperties(File file) { jjg@201: Properties p = new Properties(); jjg@201: if (file != null && file.exists()) { jjg@201: Reader in = null; jjg@201: try { jjg@201: in = new BufferedReader(new FileReader(file)); jjg@201: p.load(in); jjg@201: in.close(); jjg@201: } catch (IOException e) { jjg@201: throw new BuildException("error reading property file", e); jjg@201: } finally { jjg@201: if (in != null) { jjg@201: try { jjg@201: in.close(); jjg@201: } catch (IOException e) { jjg@201: throw new BuildException("cannot close property file", e); jjg@201: } jjg@201: } jjg@201: } jjg@201: } jjg@201: return p; jjg@201: } jjg@201: jjg@201: void writeProperties(File file, Properties p) { jjg@201: if (file != null) { jjg@201: Writer out = null; jjg@201: try { jjg@201: File dir = file.getParentFile(); jjg@201: if (dir != null && !dir.exists()) jjg@201: dir.mkdirs(); jjg@201: out = new BufferedWriter(new FileWriter(file)); jjg@201: p.store(out, "langtools properties"); jjg@201: out.close(); jjg@201: } catch (IOException e) { jjg@201: throw new BuildException("error writing property file", e); jjg@201: } finally { jjg@201: if (out != null) { jjg@201: try { jjg@201: out.close(); jjg@201: } catch (IOException e) { jjg@201: throw new BuildException("cannot close property file", e); jjg@201: } jjg@201: } jjg@201: } jjg@201: } jjg@201: } jjg@201: jjg@201: String getDefaultArgsForTool(Properties props, String tn) { jjg@201: return (tn == null || tn.equals("")) ? "" : props.getProperty(tn + ".args", ""); jjg@201: } jjg@201: jjg@201: // Ant task parameters jjg@201: private boolean askIfUnset; jjg@201: private String toolProperty; jjg@201: private String argsProperty; jjg@201: private File propertyFile; jjg@201: jjg@201: // GUI components jjg@201: private JComboBox toolChoice; jjg@201: private JTextField argsField; jjg@201: private JCheckBox defaultCheck; jjg@201: private JButton okButton; jjg@201: jjg@201: // Result values for the client jjg@201: private String toolName; jjg@201: private String toolArgs; jjg@201: }