001: package tide.exttools.lint4j;
002:
003: import java.net.URL;
004: import tide.project.*;
005: import tide.editor.*;
006: import javax.swing.*;
007: import java.awt.*;
008: import java.awt.event.*;
009: import javax.swing.border.*;
010: import java.util.*;
011: import java.io.*;
012: import snow.utils.*;
013: import snow.utils.storage.*;
014: import snow.utils.gui.*;
015:
016: /** The settings of Lint4J
017: */
018: public class Lint4JSettingsDialog extends JDialog {
019: private final FileField jlintPath = new FileField("", false,
020: "Give the Lint4J jar file location",
021: JFileChooser.FILES_ONLY);
022: final private JButton viewOpts = new JButton("available options");
023: public boolean dialogWasAccepted = false;
024:
025: public static final String defaultLint4JPath = "C:/Java/lint4j-0.9.1/jars/lint4j.jar";
026: public final static String homepage = "http://www.jutils.com";
027: public final static String directDownloadLink = "http://www.jutils.com/download/lint4j/lint4j-0.9.1.zip";
028:
029: public Lint4JSettingsDialog(final JFrame parent,
030: final ProjectSettings settings) {
031: super (parent, "Lint4J sourcecode checker", true);
032:
033: JComponent ta = GUIUtils
034: .createReadOnlyDescriptionArea("Lint4j (\"Lint for Java\") is a static Java source and bytecode code analyzer that detects locking"
035: + "\nand threading issues, performance and scalability problems, and checks complex contracts such as"
036: + "\nJava serialization by performing type, data flow, and lock graph analysis."
037: + "\n\nLint4j was created to help software developers detect defects in Java source code."
038: + "\nIt is a code reviewer for new code, and an early warning tool for codebases that were"
039: + "\ndeveloped by third-party companies or come from the open-source world. Lint4j is targeted"
040: + "\ntowards developers, and helps finding many problems before even running the software or"
041: + "\nwriting the first test case."
042: + "\n"
043: + "\nPlease visit "
044: + homepage
045: + " for the most up-to-date documentation."
046: + "\n\nUSAGE: launch Lint4J from the context menu of the sources tree, for single files or branches.");
047: add(ta, BorderLayout.NORTH);
048:
049: JPanel inputPanel = new JPanel();
050: add(inputPanel, BorderLayout.CENTER);
051: GridLayout3 gl3 = new GridLayout3(2, inputPanel);
052:
053: JButton help = new JButton("Lint4J Homepage", Icons
054: .createHelpIcon(16, true));
055: help.setMargin(new Insets(0, 2, 0, 2));
056: help.setFocusPainted(false);
057: gl3.addSeparator();
058: gl3.add(help);
059: help.addActionListener(new ActionListener() {
060: public void actionPerformed(ActionEvent ae) {
061: try {
062: SysUtils.openBrowser(homepage);
063: } catch (Exception e) {
064: JOptionPane.showMessageDialog(null,
065: "Can't open browser for " + homepage
066: + "\nerr:" + e.getMessage(),
067: "Error", JOptionPane.ERROR_MESSAGE);
068: }
069: }
070: });
071:
072: final JButton down = new JButton(
073: "Download and install version 0.9.1",
074: Icons.sharedDownArrow);
075: down.setMargin(new Insets(0, 2, 0, 2));
076: down.setFocusPainted(false);
077: gl3.add(down);
078: down.addActionListener(new ActionListener() {
079: public void actionPerformed(ActionEvent ae) {
080: final long[] ds;
081: final URL url;
082: try {
083: url = new URL(directDownloadLink);
084: ds = NetUtils.getDateAndSizeOnServer(url);
085: } catch (Exception ex) {
086: JOptionPane.showMessageDialog(null,
087: "Cannot download Lint4J (are you online?):\n "
088: + ex.getMessage(), "Error",
089: JOptionPane.ERROR_MESSAGE);
090: return;
091: }
092:
093: final JFileChooser fs = new JFileChooser();
094: fs
095: .setDialogTitle("Choose the folder to install Lint4J in");
096: fs.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
097: fs
098: .setApproveButtonText("Download and install Lint4J in this folder");
099: int rep = fs.showOpenDialog(Lint4JSettingsDialog.this );
100: if (rep != fs.APPROVE_OPTION)
101: return;
102:
103: final File destFolder = fs.getSelectedFile();
104:
105: final ProgressModalDialog pmd = new ProgressModalDialog(
106: Lint4JSettingsDialog.this , "Download Lint4J",
107: true);
108: pmd.setProgressBounds(100);
109: pmd.start();
110: final File tempDest = new File(destFolder,
111: "lint4j-0.9.1.zip");
112: Thread t = new Thread() {
113: @Override
114: public void run() {
115: try {
116: pmd
117: .setProgressSection("Downloading Lint4j from sourceforge");
118: pmd
119: .setProgressComment("lint4j-0.9.1 (4MB)");
120: NetUtils.downloadFileFromServer(url,
121: tempDest, "lint4j-0.9.1", pmd);
122:
123: // ok, => install
124: pmd
125: .setProgressSection("Unpacking FindBugs locally");
126: FileUtils.extractZipFile(tempDest,
127: destFolder, pmd);
128:
129: // link
130: File pf = new File(destFolder,
131: "lint4j-0.9.1/jars/lint4j.jar");
132:
133: jlintPath.setPath(pf);
134: // todo: look if exist !!
135: } catch (Exception ex) {
136: JOptionPane.showMessageDialog(null,
137: "Cannot download Lint4J:\n "
138: + ex.getMessage(), "Error",
139: JOptionPane.ERROR_MESSAGE);
140: ex.printStackTrace();
141: } finally {
142: pmd.closeDialog();
143: }
144: }
145: };
146: t.start();
147: }
148: });
149:
150: gl3.addSeparator();
151:
152: gl3.add("Lint4J application (Jar file)");
153: gl3.add(jlintPath);
154: jlintPath.setPath(settings.getProperty("Lint4J_path",
155: defaultLint4JPath));
156: if (MainEditorFrame.instance != null)
157: jlintPath.offerRememberedGlobalCompletion(
158: MainEditorFrame.instance.globalProperties,
159: "knownLint4Js");
160: jlintPath.setComponentWidth(350);
161: jlintPath.allowedExtensions.add("jar");
162: jlintPath.fileTypeDescription = "Jar archive (Java application)";
163: jlintPath.setAutoColorized();
164:
165: gl3.add("Options");
166: JPanel argumentsPanel = new JPanel(new FlowLayout(
167: FlowLayout.LEFT, 0, 0));
168: viewOpts.setMargin(new Insets(0, 2, 0, 2));
169: viewOpts.setFocusPainted(false);
170: JTextField argsField = new JTextField(settings.getProperty(
171: "Lint4J_Options", "-v 3"), 25); // (-v 3: 1 severe - 5 suggestion)
172: gl3.add(argumentsPanel);
173: argumentsPanel.add(argsField);
174: argumentsPanel.add(viewOpts);
175: viewOpts.addActionListener(new ActionListener() {
176: public void actionPerformed(ActionEvent ae) {
177: displayOptions();
178: }
179: });
180:
181: gl3.add("");
182: final JCheckBox autoRemIrrelevant = new JCheckBox(
183: "Auto remove messages declared as irrelevant", settings
184: .getBooleanProperty("Lint4J_ignoreIrrelevant",
185: false));
186: gl3.add(autoRemIrrelevant);
187:
188: CloseControlPanel ccp = new CloseControlPanel(this , true, true,
189: "Ok");
190: add(ccp, BorderLayout.SOUTH);
191:
192: pack();
193: this .setLocationRelativeTo(parent);
194: this .setVisible(true); // MODAL => waits
195:
196: if (ccp.getWasCancelled())
197: return;
198: dialogWasAccepted = true;
199:
200: // save settings
201: settings.setProperty("Lint4J_path", jlintPath.getPath()
202: .getAbsolutePath());
203: settings.setProperty("Lint4J_Options", argsField.getText());
204: settings.setBooleanProperty("Lint4J_ignoreIrrelevant",
205: autoRemIrrelevant.isSelected());
206:
207: jlintPath.rememberPathForGlobalCompletion(
208: MainEditorFrame.instance.globalProperties,
209: "knownLint4Js");
210:
211: } // Constructor
212:
213: /** @return true if Lint4j path is present.
214: Used to detect if a setup dialog should be shown when starting the tool (if not found).
215: */
216: public static boolean isConfigured() {
217: final ProjectSettings actualProject = MainEditorFrame.instance
218: .getActualProject();
219: return new File(actualProject.getProperty("Lint4J_path",
220: defaultLint4JPath)).exists();
221: }
222:
223: private void displayOptions() {
224: final ProjectSettings actualProject = MainEditorFrame.instance
225: .getActualProject();
226: final StringBuilder comp = new StringBuilder();
227: try {
228: comp.append(ProcessUtils.readWholeProcessStack(
229: actualProject.getJava_TOOL().getAbsolutePath(),
230: "-jar", jlintPath.getPath().getAbsolutePath(),
231: "-help"));
232: //? comp.append("\r\nYou can also pass the option -J-Xmx256m to increase the memory for large projects doc creation");
233: } catch (Exception e) {
234: comp.append("\r\nError: " + e.getMessage());
235: e.printStackTrace();
236: }
237:
238: final JDialog optionsDialog = new JDialog(this ,
239: "Available Lint4J options", false);
240: JTextPane tp = new JTextPane();
241: tp.setFont(MainEditorFrame.fixedWidthFontForProcesses);
242: tp.setText(comp.toString().trim());
243: optionsDialog.add(new JScrollPane(tp), BorderLayout.CENTER);
244: CloseControlPanel ccp = new CloseControlPanel(optionsDialog,
245: false, true, "Close");
246: optionsDialog.add(ccp, BorderLayout.SOUTH);
247: tp.setEditable(false);
248: tp.setCaretPosition(0);
249: optionsDialog.setSize(800, 550);
250: optionsDialog.setLocationRelativeTo(viewOpts);
251: optionsDialog.setVisible(true);
252: }
253: /*
254: public static void main(String[] aa)
255: {
256: JFrame f = new JFrame("Test");
257: f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
258: ProjectSettings props = new ProjectSettings();
259: new Lint4JSettingsDialog(f, props);
260: System.exit(0);
261: }*/
262: }
|