PageRenderTime 73ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/netbeans-7.3/code.analysis/src/org/netbeans/modules/analysis/RunAnalysisPanel.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 1034 lines | 811 code | 165 blank | 58 comment | 115 complexity | 2d2c3b440616b93834f23136ef83c7a2 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * If you wish your version of this file to be governed by only the CDDL
  28. * or only the GPL Version 2, indicate your decision by adding
  29. * "[Contributor] elects to include this software in this distribution
  30. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  31. * single choice of license, a recipient has the option to distribute
  32. * your version of this file under either the CDDL, the GPL Version 2 or
  33. * to extend the choice of license to its licensees as provided above.
  34. * However, if you add GPL Version 2 code and therefore, elected the GPL
  35. * Version 2 license, then the option applies only if the new code is
  36. * made subject to such option by the copyright holder.
  37. *
  38. * Contributor(s):
  39. *
  40. * Portions Copyrighted 2012 Sun Microsystems, Inc.
  41. */
  42. package org.netbeans.modules.analysis;
  43. import java.awt.CardLayout;
  44. import java.awt.Color;
  45. import java.awt.Component;
  46. import java.awt.Font;
  47. import java.awt.Graphics;
  48. import java.awt.GridBagConstraints;
  49. import java.awt.Insets;
  50. import java.awt.event.ActionEvent;
  51. import java.awt.event.ActionListener;
  52. import java.beans.BeanInfo;
  53. import java.util.ArrayList;
  54. import java.util.Collection;
  55. import java.util.Collections;
  56. import java.util.Comparator;
  57. import java.util.HashMap;
  58. import java.util.HashSet;
  59. import java.util.LinkedList;
  60. import java.util.List;
  61. import java.util.Map;
  62. import java.util.Map.Entry;
  63. import java.util.Set;
  64. import java.util.TreeMap;
  65. import java.util.TreeSet;
  66. import java.util.concurrent.atomic.AtomicBoolean;
  67. import java.util.logging.Level;
  68. import java.util.logging.Logger;
  69. import java.util.prefs.Preferences;
  70. import javax.swing.DefaultComboBoxModel;
  71. import javax.swing.DefaultListCellRenderer;
  72. import javax.swing.Icon;
  73. import javax.swing.JButton;
  74. import javax.swing.JComponent;
  75. import javax.swing.JList;
  76. import javax.swing.JPanel;
  77. import javax.swing.SwingUtilities;
  78. import javax.swing.UIManager;
  79. import javax.swing.border.Border;
  80. import javax.swing.border.EmptyBorder;
  81. import javax.swing.event.ChangeEvent;
  82. import javax.swing.event.ChangeListener;
  83. import org.netbeans.api.fileinfo.NonRecursiveFolder;
  84. import org.netbeans.api.java.classpath.ClassPath;
  85. import org.netbeans.api.progress.ProgressHandle;
  86. import org.netbeans.api.progress.ProgressHandleFactory;
  87. import org.netbeans.api.project.FileOwnerQuery;
  88. import org.netbeans.api.project.Project;
  89. import org.netbeans.api.project.ProjectInformation;
  90. import org.netbeans.api.project.ProjectUtils;
  91. import org.netbeans.api.project.SourceGroup;
  92. import org.netbeans.api.project.ui.OpenProjects;
  93. import org.netbeans.modules.analysis.spi.Analyzer.AnalyzerFactory;
  94. import org.netbeans.modules.analysis.spi.Analyzer.Context;
  95. import org.netbeans.modules.analysis.spi.Analyzer.MissingPlugin;
  96. import org.netbeans.modules.analysis.spi.Analyzer.WarningDescription;
  97. import org.netbeans.modules.analysis.ui.AdjustConfigurationPanel;
  98. import org.netbeans.modules.analysis.ui.ConfigurationsComboModel;
  99. import org.netbeans.modules.refactoring.api.Scope;
  100. import org.openide.DialogDescriptor;
  101. import org.openide.DialogDisplayer;
  102. import org.openide.NotifyDescriptor;
  103. import org.openide.filesystems.FileObject;
  104. import org.openide.loaders.DataFolder;
  105. import org.openide.loaders.DataObject;
  106. import org.openide.loaders.DataObjectNotFoundException;
  107. import org.openide.nodes.Node;
  108. import org.openide.util.ImageUtilities;
  109. import org.openide.util.Lookup;
  110. import org.openide.util.LookupEvent;
  111. import org.openide.util.LookupListener;
  112. import org.openide.util.NbBundle.Messages;
  113. import org.openide.util.NbPreferences;
  114. import org.openide.util.RequestProcessor;
  115. /**
  116. *
  117. * @author lahvac
  118. */
  119. public final class RunAnalysisPanel extends javax.swing.JPanel implements LookupListener {
  120. private static final String COMBO_PROTOTYPE = "999999999999999999999999999999999999999999999999999999999999";
  121. private static final RequestProcessor WORKER = new RequestProcessor(RunAnalysisPanel.class.getName(), 1, false, false);
  122. private final JPanel progress;
  123. private final RequiredPluginsPanel requiredPlugins;
  124. //GuardedBy(AWT)
  125. private Collection<? extends AnalyzerFactory> analyzers;
  126. //GuardedBy(AWT)
  127. private FutureWarnings analyzer2Warnings;
  128. private final Lookup.Result<AnalyzerFactory> analyzersResult;
  129. private final Map<String, AnalyzerAndWarning> warningId2Description = new HashMap<String, AnalyzerAndWarning>();
  130. private final JButton runAnalysis;
  131. //GuardedBy(AWT)
  132. private boolean inspectionsReady;
  133. private boolean started;
  134. public RunAnalysisPanel(ProgressHandle handle, Lookup context, JButton runAnalysis) {
  135. this(handle, context, runAnalysis, null);
  136. }
  137. public RunAnalysisPanel(ProgressHandle handle, Lookup context, JButton runAnalysis, DialogState state) {
  138. this.runAnalysis = runAnalysis;
  139. this.analyzersResult = Lookup.getDefault().lookupResult(AnalyzerFactory.class);
  140. this.analyzersResult.addLookupListener(this);
  141. initComponents();
  142. List<ScopeDescription> scopes = new ArrayList<ScopeDescription>();
  143. Icon currentProjectIcon = null;
  144. NonRecursiveFolder pack = context.lookup(NonRecursiveFolder.class);
  145. FileObject currentFile = context.lookup(FileObject.class);
  146. if (currentFile != null && currentFile.isData()) {
  147. scopes.add(new FileScopeDescription(currentFile));
  148. }
  149. if (pack != null && currentFile == null) {
  150. currentFile = pack.getFolder();
  151. }
  152. if (currentFile != null) {
  153. Project p = FileOwnerQuery.getOwner(currentFile);
  154. if (p != null) {
  155. ProjectInformation pi = ProjectUtils.getInformation(p);
  156. scopes.add(0, new CurrentProjectScopeDescription(p));
  157. currentProjectIcon = pi.getIcon();
  158. if (pack == null) {
  159. ClassPath bootCP = ClassPath.getClassPath(currentFile, ClassPath.BOOT);
  160. if (bootCP != null) {
  161. final FileObject packFO = currentFile.getParent();
  162. pack = new NonRecursiveFolder() {
  163. @Override public FileObject getFolder() {
  164. return packFO;
  165. }
  166. };
  167. }
  168. }
  169. }
  170. } else {
  171. Project selected = context.lookup(Project.class);
  172. if (selected == null) {
  173. SourceGroup sg = context.lookup(SourceGroup.class);
  174. if (sg != null) {
  175. selected = FileOwnerQuery.getOwner(sg.getRootFolder());
  176. }
  177. }
  178. if (selected == null) {
  179. DataFolder df = context.lookup(DataFolder.class);
  180. if (df != null) {
  181. selected = FileOwnerQuery.getOwner(df.getPrimaryFile());
  182. }
  183. }
  184. if (selected != null) {
  185. ProjectInformation pi = ProjectUtils.getInformation(selected);
  186. scopes.add(0, new CurrentProjectScopeDescription(selected));
  187. currentProjectIcon = pi.getIcon();
  188. }
  189. }
  190. if (pack != null) {
  191. ClassPath source = ClassPath.getClassPath(pack.getFolder(), ClassPath.SOURCE);
  192. if (source != null) {
  193. String packName = source.getResourceName(pack.getFolder());
  194. scopes.add(1, new PackageScopeDescription(pack, packName));
  195. }
  196. }
  197. scopes.add(0, new AllProjectsScopeDescription(currentProjectIcon));
  198. scopeCombo.setModel(new DefaultComboBoxModel(scopes.toArray(new ScopeDescription[0])));
  199. scopeCombo.setRenderer(new ScopeRenderer());
  200. scopeCombo.setSelectedIndex(scopes.size() - 1);
  201. GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints();
  202. gridBagConstraints.gridx = 0;
  203. gridBagConstraints.gridy = 3;
  204. gridBagConstraints.gridwidth = 4;
  205. gridBagConstraints.gridheight = 1;
  206. gridBagConstraints.weightx = 1;
  207. gridBagConstraints.fill = GridBagConstraints.HORIZONTAL;
  208. gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
  209. gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0);
  210. progress = new JPanel(new CardLayout());
  211. progress.add(new JPanel(), "empty");
  212. progress.add(ProgressHandleFactory.createProgressComponent(handle), "progress");
  213. progress.add(requiredPlugins = new RequiredPluginsPanel(), "plugins");
  214. add(progress, gridBagConstraints);
  215. ((CardLayout) progress.getLayout()).show(progress, "empty");
  216. if (state == null) state = DialogState.load();
  217. updateConfigurations(state);
  218. updateEnableDisable();
  219. setBorder(new EmptyBorder(12, 12, 12, 12));
  220. ConfigurationsManager.getDefault().addChangeListener(new ChangeListener() {
  221. @Override public void stateChanged(ChangeEvent e) {
  222. resultChanged(null);
  223. }
  224. });
  225. configurationCombo.addActionListener(new ActionListener() {
  226. Object currentItem = configurationCombo.getSelectedItem();
  227. @Override
  228. public void actionPerformed(ActionEvent e) {
  229. Object tempItem = configurationCombo.getSelectedItem();
  230. if (tempItem instanceof String) {
  231. configurationCombo.setSelectedItem(currentItem);
  232. } else {
  233. currentItem = tempItem;
  234. }
  235. }
  236. });
  237. inspectionCombo.addActionListener(new ActionListener() {
  238. Object currentItem = inspectionCombo.getSelectedItem();
  239. @Override
  240. public void actionPerformed(ActionEvent e) {
  241. Object tempItem = inspectionCombo.getSelectedItem();
  242. if (!(tempItem instanceof AnalyzerAndWarning)) {
  243. inspectionCombo.setSelectedItem(currentItem);
  244. updatePlugins();
  245. } else {
  246. currentItem = tempItem;
  247. }
  248. }
  249. });
  250. }
  251. void started() {
  252. started = true;
  253. ((CardLayout) progress.getLayout()).show(progress, "progress");
  254. progress.invalidate();
  255. //disable all elements in the dialog:
  256. List<JComponent> todo = new LinkedList<JComponent>();
  257. todo.add(this);
  258. while (!todo.isEmpty()) {
  259. JComponent c = todo.remove(0);
  260. if (c == progress) continue;
  261. c.setEnabled(false);
  262. for (Component child : c.getComponents()) {
  263. if (child instanceof JComponent) todo.add((JComponent) child);
  264. }
  265. }
  266. }
  267. @Messages({"LBL_Predefined=Predefined", "LBL_Custom=Custom", "LBL_PleaseWait=Computing..."})
  268. public void updateConfigurations(final DialogState state) {
  269. analyzers = analyzersResult.allInstances();
  270. Object selectedConfiguration = null;
  271. DefaultComboBoxModel configurationModel = new DefaultComboBoxModel();
  272. configurationModel.addElement(Bundle.LBL_Predefined());
  273. configurationModel.addElement(null);
  274. for (AnalyzerFactory analyzer : analyzers) {
  275. if (SPIAccessor.ACCESSOR.getAnalyzerId(analyzer).equals(state.selectedAnalyzer)) {
  276. selectedConfiguration = analyzer;
  277. }
  278. configurationModel.addElement(analyzer);
  279. }
  280. configurationModel.addElement(Bundle.LBL_Custom());
  281. for (Configuration c : ConfigurationsManager.getDefault().getConfigurations()) {
  282. if (c.id().equals(state.selectedConfiguration)) {
  283. selectedConfiguration = c;
  284. }
  285. configurationModel.addElement(c);
  286. }
  287. configurationCombo.setModel(configurationModel);
  288. configurationCombo.setSelectedItem(selectedConfiguration);
  289. configurationRadio.setSelected(state.configurationsSelected);
  290. configurationCombo.setRenderer(new ConfigurationRenderer(true));
  291. DefaultComboBoxModel inspectionModel = new DefaultComboBoxModel();
  292. inspectionModel.addElement(Bundle.LBL_PleaseWait());
  293. inspectionCombo.setModel(inspectionModel);
  294. inspectionCombo.setRenderer(new InspectionRenderer());
  295. inspectionCombo.setSelectedItem(0);
  296. singleInspectionRadio.setSelected(!state.configurationsSelected);
  297. updatePlugins();
  298. final Collection<? extends AnalyzerFactory> analyzersCopy = new ArrayList<AnalyzerFactory>(analyzers);
  299. inspectionsReady = false;
  300. analyzer2Warnings = new FutureWarnings();
  301. WORKER.post(new Runnable() {
  302. @Override public void run() {
  303. final Map<AnalyzerFactory, Iterable<? extends WarningDescription>> analyzer2Warnings = new HashMap<AnalyzerFactory, Iterable<? extends WarningDescription>>();
  304. for (AnalyzerFactory a : analyzersCopy) {
  305. List<WarningDescription> warnings = new ArrayList<WarningDescription>();
  306. for (WarningDescription wd : a.getWarnings()) {
  307. warnings.add(wd);
  308. }
  309. analyzer2Warnings.put(a, warnings);
  310. }
  311. final Map<AnalyzerFactory, Map<String, WarningDescription>> analyzer2Id2DescriptionVal = computeAnalyzerId2Description(analyzer2Warnings);
  312. SwingUtilities.invokeLater(new Runnable() {
  313. @Override public void run() {
  314. RunAnalysisPanel.this.analyzer2Warnings.set(analyzer2Id2DescriptionVal);
  315. fillInspectionCombo(state, analyzer2Warnings);
  316. inspectionsReady = true;
  317. updatePlugins();
  318. }
  319. });
  320. }
  321. });
  322. }
  323. private void fillInspectionCombo(DialogState state, Map<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> analyzer2Warnings) {
  324. DefaultComboBoxModel inspectionModel = new DefaultComboBoxModel();
  325. AnalyzerAndWarning firstInspection = null;
  326. AnalyzerAndWarning preselectInspection = null;
  327. for (Entry<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> e : analyzer2Warnings.entrySet()) {
  328. inspectionModel.addElement(SPIAccessor.ACCESSOR.getAnalyzerDisplayName(e.getKey()));
  329. Map<String, Collection<WarningDescription>> cat2Warnings = new TreeMap<String, Collection<WarningDescription>>();
  330. for (WarningDescription wd : e.getValue()) {
  331. String cat = SPIAccessor.ACCESSOR.getWarningCategoryDisplayName(wd); //TODO: should be based on the id rather than on the display name
  332. Collection<WarningDescription> warnings = cat2Warnings.get(cat);
  333. if (warnings == null) {
  334. cat2Warnings.put(cat, warnings = new TreeSet<WarningDescription>(new Comparator<WarningDescription>() {
  335. @Override public int compare(WarningDescription o1, WarningDescription o2) {
  336. return SPIAccessor.ACCESSOR.getWarningDisplayName(o1).compareToIgnoreCase(SPIAccessor.ACCESSOR.getWarningDisplayName(o2));
  337. }
  338. }));
  339. }
  340. warnings.add(wd);
  341. }
  342. for (Entry<String, Collection<WarningDescription>> catE : cat2Warnings.entrySet()) {
  343. inspectionModel.addElement(" " + catE.getKey());
  344. for (WarningDescription wd : catE.getValue()) {
  345. AnalyzerAndWarning aaw = new AnalyzerAndWarning(e.getKey(), wd);
  346. inspectionModel.addElement(aaw);
  347. warningId2Description.put(SPIAccessor.ACCESSOR.getWarningId(wd), aaw);
  348. if (firstInspection == null) firstInspection = aaw;
  349. if (SPIAccessor.ACCESSOR.getWarningId(wd).equals(state.selectedInspection)) {
  350. preselectInspection = aaw;
  351. }
  352. }
  353. }
  354. }
  355. inspectionCombo.setModel(inspectionModel);
  356. inspectionCombo.setSelectedItem(preselectInspection != null ? preselectInspection : firstInspection);
  357. }
  358. private void updatePlugins() {
  359. if (started) return ;
  360. Collection<? extends AnalyzerFactory> toRun;
  361. if (singleInspectionRadio.isSelected()) {
  362. if (!inspectionsReady) {
  363. runAnalysis.setEnabled(false);
  364. return ;
  365. }
  366. Object selectedInspection = inspectionCombo.getSelectedItem();
  367. if (selectedInspection instanceof AnalyzerAndWarning) {
  368. toRun = Collections.singleton(((AnalyzerAndWarning) selectedInspection).analyzer);
  369. } else {
  370. toRun = Collections.emptyList();
  371. }
  372. } else {
  373. if (!(configurationCombo.getSelectedItem() instanceof AnalyzerFactory)) {
  374. toRun = analyzers;
  375. } else {
  376. toRun = Collections.singleton((AnalyzerFactory) configurationCombo.getSelectedItem());
  377. }
  378. }
  379. Context ctx = SPIAccessor.ACCESSOR.createContext(null, null, null, null, -1, -1);
  380. Set<MissingPlugin> plugins = new HashSet<MissingPlugin>();
  381. boolean someOk = false;
  382. for (AnalyzerFactory a : toRun) {
  383. Collection<? extends MissingPlugin> req = a.requiredPlugins(ctx);
  384. plugins.addAll(req);
  385. someOk |= req.isEmpty();
  386. }
  387. if (plugins.isEmpty()) {
  388. ((CardLayout) progress.getLayout()).show(progress, "empty");
  389. } else {
  390. requiredPlugins.setRequiredPlugins(plugins, !someOk);
  391. ((CardLayout) progress.getLayout()).show(progress, "plugins");
  392. }
  393. runAnalysis.setEnabled(someOk);
  394. }
  395. public Scope getSelectedScope(AtomicBoolean cancel) {
  396. return ((ScopeDescription) scopeCombo.getSelectedItem()).getScope(cancel);
  397. }
  398. public AnalyzerFactory getSelectedAnalyzer() {
  399. if (singleInspectionRadio.isSelected()) {
  400. Object singleInspection = inspectionCombo.getSelectedItem();
  401. if (singleInspection instanceof AnalyzerAndWarning) {
  402. return ((AnalyzerAndWarning) singleInspection).analyzer;
  403. }
  404. return null;
  405. }
  406. if (!(configurationCombo.getSelectedItem() instanceof AnalyzerFactory)) return null;
  407. return (AnalyzerFactory) configurationCombo.getSelectedItem();
  408. }
  409. public Configuration getConfiguration() {
  410. if (inspectionCombo.isEnabled()) return ConfigurationsManager.getDefault().getTemporaryConfiguration();
  411. Object selected = configurationCombo.getSelectedItem();
  412. if (selected instanceof Configuration) return (Configuration) selected;
  413. else return null;
  414. }
  415. public Collection<? extends AnalyzerFactory> getAnalyzers() {
  416. return analyzers;
  417. }
  418. /**
  419. * This method is called from within the constructor to initialize the form.
  420. * WARNING: Do NOT modify this code. The content of this method is always
  421. * regenerated by the Form Editor.
  422. */
  423. @SuppressWarnings("unchecked")
  424. // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  425. private void initComponents() {
  426. java.awt.GridBagConstraints gridBagConstraints;
  427. radioButtons = new javax.swing.ButtonGroup();
  428. jLabel1 = new javax.swing.JLabel();
  429. scopeCombo = new javax.swing.JComboBox();
  430. jLabel2 = new javax.swing.JLabel();
  431. configurationCombo = new javax.swing.JComboBox();
  432. manage = new javax.swing.JButton();
  433. configurationRadio = new javax.swing.JRadioButton();
  434. singleInspectionRadio = new javax.swing.JRadioButton();
  435. inspectionCombo = new javax.swing.JComboBox();
  436. browse = new javax.swing.JButton();
  437. setLayout(new java.awt.GridBagLayout());
  438. org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.jLabel1.text")); // NOI18N
  439. gridBagConstraints = new java.awt.GridBagConstraints();
  440. gridBagConstraints.gridx = 0;
  441. gridBagConstraints.gridy = 0;
  442. gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING;
  443. add(jLabel1, gridBagConstraints);
  444. gridBagConstraints = new java.awt.GridBagConstraints();
  445. gridBagConstraints.gridx = 1;
  446. gridBagConstraints.gridy = 0;
  447. gridBagConstraints.gridwidth = 3;
  448. gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
  449. gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING;
  450. gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0);
  451. add(scopeCombo, gridBagConstraints);
  452. org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.jLabel2.text")); // NOI18N
  453. gridBagConstraints = new java.awt.GridBagConstraints();
  454. gridBagConstraints.gridx = 0;
  455. gridBagConstraints.gridy = 1;
  456. gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING;
  457. gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0);
  458. add(jLabel2, gridBagConstraints);
  459. configurationCombo.setPrototypeDisplayValue(COMBO_PROTOTYPE);
  460. configurationCombo.addActionListener(new java.awt.event.ActionListener() {
  461. public void actionPerformed(java.awt.event.ActionEvent evt) {
  462. configurationComboActionPerformed(evt);
  463. }
  464. });
  465. gridBagConstraints = new java.awt.GridBagConstraints();
  466. gridBagConstraints.gridx = 2;
  467. gridBagConstraints.gridy = 1;
  468. gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
  469. gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING;
  470. gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
  471. add(configurationCombo, gridBagConstraints);
  472. org.openide.awt.Mnemonics.setLocalizedText(manage, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.manage.text")); // NOI18N
  473. manage.addActionListener(new java.awt.event.ActionListener() {
  474. public void actionPerformed(java.awt.event.ActionEvent evt) {
  475. manageActionPerformed(evt);
  476. }
  477. });
  478. gridBagConstraints = new java.awt.GridBagConstraints();
  479. gridBagConstraints.gridx = 3;
  480. gridBagConstraints.gridy = 1;
  481. gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
  482. gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
  483. add(manage, gridBagConstraints);
  484. radioButtons.add(configurationRadio);
  485. org.openide.awt.Mnemonics.setLocalizedText(configurationRadio, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.configurationRadio.text")); // NOI18N
  486. configurationRadio.addActionListener(new java.awt.event.ActionListener() {
  487. public void actionPerformed(java.awt.event.ActionEvent evt) {
  488. configurationRadioActionPerformed(evt);
  489. }
  490. });
  491. gridBagConstraints = new java.awt.GridBagConstraints();
  492. gridBagConstraints.gridx = 1;
  493. gridBagConstraints.gridy = 1;
  494. gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
  495. gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
  496. add(configurationRadio, gridBagConstraints);
  497. radioButtons.add(singleInspectionRadio);
  498. org.openide.awt.Mnemonics.setLocalizedText(singleInspectionRadio, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.singleInspectionRadio.text")); // NOI18N
  499. singleInspectionRadio.addActionListener(new java.awt.event.ActionListener() {
  500. public void actionPerformed(java.awt.event.ActionEvent evt) {
  501. singleInspectionRadioActionPerformed(evt);
  502. }
  503. });
  504. gridBagConstraints = new java.awt.GridBagConstraints();
  505. gridBagConstraints.gridx = 1;
  506. gridBagConstraints.gridy = 2;
  507. gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE_LEADING;
  508. gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
  509. add(singleInspectionRadio, gridBagConstraints);
  510. inspectionCombo.setPrototypeDisplayValue(COMBO_PROTOTYPE);
  511. gridBagConstraints = new java.awt.GridBagConstraints();
  512. gridBagConstraints.gridx = 2;
  513. gridBagConstraints.gridy = 2;
  514. gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
  515. gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE;
  516. gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
  517. add(inspectionCombo, gridBagConstraints);
  518. org.openide.awt.Mnemonics.setLocalizedText(browse, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.browse.text")); // NOI18N
  519. browse.addActionListener(new java.awt.event.ActionListener() {
  520. public void actionPerformed(java.awt.event.ActionEvent evt) {
  521. browseActionPerformed(evt);
  522. }
  523. });
  524. gridBagConstraints = new java.awt.GridBagConstraints();
  525. gridBagConstraints.gridx = 3;
  526. gridBagConstraints.gridy = 2;
  527. gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
  528. gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE;
  529. gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0);
  530. add(browse, gridBagConstraints);
  531. }// </editor-fold>//GEN-END:initComponents
  532. private void configurationComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configurationComboActionPerformed
  533. updatePlugins();
  534. }//GEN-LAST:event_configurationComboActionPerformed
  535. @Messages("LBL_Configurations=Configurations")
  536. private void manageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageActionPerformed
  537. AdjustConfigurationPanel panel = new AdjustConfigurationPanel(analyzers, null, null);
  538. DialogDescriptor nd = new DialogDescriptor(panel, Bundle.LBL_Configurations(), true, NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.OK_OPTION, null);
  539. if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.OK_OPTION) {
  540. panel.save();
  541. }
  542. }//GEN-LAST:event_manageActionPerformed
  543. private void configurationRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configurationRadioActionPerformed
  544. updateEnableDisable();
  545. }//GEN-LAST:event_configurationRadioActionPerformed
  546. private void singleInspectionRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_singleInspectionRadioActionPerformed
  547. updateEnableDisable();
  548. }//GEN-LAST:event_singleInspectionRadioActionPerformed
  549. @Messages("LBL_Browse=Browse Inspections")
  550. private void browseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseActionPerformed
  551. Object selectedInspection = inspectionCombo.getSelectedItem();
  552. AnalyzerFactory analyzerToSelect;
  553. String warningToSelect;
  554. if (selectedInspection instanceof AnalyzerAndWarning) {
  555. analyzerToSelect = ((AnalyzerAndWarning) selectedInspection).analyzer;
  556. warningToSelect = SPIAccessor.ACCESSOR.getWarningId(((AnalyzerAndWarning) selectedInspection).wd);
  557. } else {
  558. analyzerToSelect = null;
  559. warningToSelect = "";
  560. }
  561. AdjustConfigurationPanel panel = new AdjustConfigurationPanel(analyzers, analyzerToSelect, warningToSelect);
  562. DialogDescriptor nd = new DialogDescriptor(panel, Bundle.LBL_Browse(), true, NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.OK_OPTION, null);
  563. if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.OK_OPTION) {
  564. inspectionCombo.setSelectedItem(warningId2Description.get(panel.getIdToRun()));
  565. }
  566. }//GEN-LAST:event_browseActionPerformed
  567. // Variables declaration - do not modify//GEN-BEGIN:variables
  568. private javax.swing.JButton browse;
  569. private javax.swing.JComboBox configurationCombo;
  570. private javax.swing.JRadioButton configurationRadio;
  571. private javax.swing.JComboBox inspectionCombo;
  572. private javax.swing.JLabel jLabel1;
  573. private javax.swing.JLabel jLabel2;
  574. private javax.swing.JButton manage;
  575. private javax.swing.ButtonGroup radioButtons;
  576. private javax.swing.JComboBox scopeCombo;
  577. private javax.swing.JRadioButton singleInspectionRadio;
  578. // End of variables declaration//GEN-END:variables
  579. private void updateEnableDisable() {
  580. if (started) return ;
  581. boolean configuration = configurationRadio.isSelected();
  582. configurationCombo.setEnabled(configuration);
  583. manage.setEnabled(configuration);
  584. inspectionCombo.setEnabled(!configuration);
  585. browse.setEnabled(!configuration);
  586. updatePlugins();
  587. }
  588. String getSingleWarningId() {
  589. return inspectionCombo.isEnabled() ? SPIAccessor.ACCESSOR.getWarningId(((AnalyzerAndWarning) inspectionCombo.getSelectedItem()).wd) : null;
  590. }
  591. @Override
  592. public void resultChanged(LookupEvent ev) {
  593. SwingUtilities.invokeLater(new Runnable() {
  594. @Override public void run() {
  595. updateConfigurations(getDialogState());
  596. }
  597. });
  598. }
  599. public DialogState getDialogState() {
  600. Object selectedConfiguration = configurationCombo.getSelectedItem();
  601. Object selectedInspection = inspectionCombo.getSelectedItem();
  602. return new DialogState(configurationRadio.isSelected(),
  603. selectedConfiguration instanceof AnalyzerFactory ? SPIAccessor.ACCESSOR.getAnalyzerId((AnalyzerFactory) selectedConfiguration) : null,
  604. selectedConfiguration instanceof Configuration ? ((Configuration) selectedConfiguration).id() : null,
  605. selectedInspection instanceof AnalyzerAndWarning ? SPIAccessor.ACCESSOR.getWarningId(((AnalyzerAndWarning) selectedInspection).wd) : null);
  606. }
  607. FutureWarnings getAnalyzerId2Description() {
  608. return analyzer2Warnings;
  609. }
  610. private static Map<AnalyzerFactory, Map<String, WarningDescription>> computeAnalyzerId2Description(Map<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> analyzer2Warnings) {
  611. Map<AnalyzerFactory, Map<String, WarningDescription>> result = new HashMap<AnalyzerFactory, Map<String, WarningDescription>>();
  612. for (Entry<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> e : analyzer2Warnings.entrySet()) {
  613. Map<String, WarningDescription> perAnalyzer = new HashMap<String, WarningDescription>();
  614. result.put(e.getKey(), perAnalyzer);
  615. for (WarningDescription wd : e.getValue()) {
  616. perAnalyzer.put(SPIAccessor.ACCESSOR.getWarningId(wd), wd);
  617. }
  618. }
  619. return result;
  620. }
  621. public static final class ConfigurationRenderer extends DefaultListCellRenderer {
  622. private final boolean indent;
  623. public ConfigurationRenderer(boolean indent) {
  624. this.indent = indent;
  625. }
  626. @Messages({"LBL_RunAllAnalyzers=All Analyzers", "# {0} - the analyzer that should be run", "LBL_RunAnalyzer={0}"})
  627. @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
  628. if (value == null) {
  629. value = Bundle.LBL_RunAllAnalyzers();
  630. } else if (value instanceof AnalyzerFactory) {
  631. value = Bundle.LBL_RunAnalyzer(SPIAccessor.ACCESSOR.getAnalyzerDisplayName((AnalyzerFactory) value));
  632. } else if (value instanceof Configuration) {
  633. value = ((Configuration) value).getDisplayName();
  634. } else if (value instanceof String) {
  635. setFont(getFont().deriveFont(Font.ITALIC));
  636. setText((String) value);
  637. setEnabled(false);
  638. setBackground(list.getBackground());
  639. setForeground(UIManager.getColor("Label.disabledForeground"));
  640. return this;
  641. }
  642. if (index == list.getModel().getSize()-5 && list.getModel() instanceof ConfigurationsComboModel && ((ConfigurationsComboModel) list.getModel()).canModify()) {
  643. setBorder(new Separator(list.getForeground()));
  644. } else {
  645. setBorder(null);
  646. }
  647. return super.getListCellRendererComponent(list, (indent ? " " : "") + value, index, isSelected, cellHasFocus);
  648. }
  649. }
  650. private static final class InspectionRenderer extends DefaultListCellRenderer {
  651. @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
  652. if (value instanceof AnalyzerAndWarning) {
  653. value = " " + SPIAccessor.ACCESSOR.getWarningDisplayName(((AnalyzerAndWarning) value).wd);
  654. } else if (value instanceof String) {
  655. setFont(getFont().deriveFont(Font.ITALIC));
  656. setText((String) value);
  657. setEnabled(false);
  658. setBackground(list.getBackground());
  659. setForeground(UIManager.getColor("Label.disabledForeground"));
  660. return this;
  661. }
  662. return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  663. }
  664. }
  665. private interface ScopeDescription {
  666. public String getDisplayName();
  667. public Icon getIcon();
  668. public Scope getScope(AtomicBoolean cancel);
  669. }
  670. private static final class AllProjectsScopeDescription implements ScopeDescription {
  671. private final Icon icon;
  672. public AllProjectsScopeDescription(Icon icon) {
  673. this.icon = icon;
  674. }
  675. @Override
  676. @Messages("DN_OpenProjects=Open Projects")
  677. public String getDisplayName() {
  678. return Bundle.DN_OpenProjects();
  679. }
  680. @Override
  681. public Icon getIcon() {
  682. return icon;
  683. }
  684. @Override
  685. public Scope getScope(AtomicBoolean cancel) {
  686. Map<Project, Map<FileObject, ClassPath>> projects2RegisteredContent = RunAnalysis.projects2RegisteredContent(cancel);
  687. if (cancel.get()) return null;
  688. Scope target = Scope.create(null, null, null);
  689. for (Project p : OpenProjects.getDefault().getOpenProjects()) {
  690. if (cancel.get()) return null;
  691. target = RunAnalysis.addProjectToScope(p, target, cancel, projects2RegisteredContent);
  692. }
  693. return target;
  694. }
  695. }
  696. private static final class CurrentProjectScopeDescription implements ScopeDescription {
  697. private final Project project;
  698. public CurrentProjectScopeDescription(Project project) {
  699. this.project = project;
  700. }
  701. @Override
  702. @Messages({"# {0} - project display name", "DN_CurrentProject=Current Project ({0})"})
  703. public String getDisplayName() {
  704. return Bundle.DN_CurrentProject(ProjectUtils.getInformation(project).getDisplayName());
  705. }
  706. @Override
  707. public Icon getIcon() {
  708. return ProjectUtils.getInformation(project).getIcon();
  709. }
  710. @Override
  711. public Scope getScope(AtomicBoolean cancel) {
  712. Map<Project, Map<FileObject, ClassPath>> projects2RegisteredContent = RunAnalysis.projects2RegisteredContent(cancel);
  713. if (cancel.get()) return null;
  714. return RunAnalysis.addProjectToScope(project, Scope.create(null, null, null), cancel, projects2RegisteredContent);
  715. }
  716. }
  717. private static final class PackageScopeDescription implements ScopeDescription {
  718. private final NonRecursiveFolder pack;
  719. private final String packName;
  720. public PackageScopeDescription(NonRecursiveFolder pack, String packName) {
  721. this.pack = pack;
  722. this.packName = packName;
  723. }
  724. @Override
  725. @Messages({"# {0} - package display name", "DN_CurrentPackage=Current Package ({0})"})
  726. public String getDisplayName() {
  727. return Bundle.DN_CurrentPackage(packName);
  728. }
  729. @Override
  730. public Icon getIcon() {
  731. return ImageUtilities.loadImageIcon("org/netbeans/modules/analysis/ui/resources/package.gif", false);
  732. }
  733. @Override
  734. public Scope getScope(AtomicBoolean cancel) {
  735. return Scope.create(null, Collections.singletonList(pack), null);
  736. }
  737. }
  738. private static final class FileScopeDescription implements ScopeDescription {
  739. private static final Logger LOG = Logger.getLogger(FileScopeDescription.class.getName());
  740. private final FileObject file;
  741. public FileScopeDescription(FileObject file) {
  742. this.file = file;
  743. }
  744. @Override
  745. @Messages({"# {0} - file display name", "DN_CurrentFile=Current File ({0})"})
  746. public String getDisplayName() {
  747. return Bundle.DN_CurrentFile(file.getNameExt());
  748. }
  749. @Override
  750. public Icon getIcon() {
  751. try {
  752. DataObject d = DataObject.find(file);
  753. Node n = d.getNodeDelegate();
  754. return ImageUtilities.image2Icon(n.getIcon(BeanInfo.ICON_COLOR_16x16));
  755. } catch (DataObjectNotFoundException ex) {
  756. LOG.log(Level.FINE, null, ex);
  757. return null;
  758. }
  759. }
  760. @Override
  761. public Scope getScope(AtomicBoolean cancel) {
  762. return Scope.create(null, null, Collections.singletonList(file));
  763. }
  764. }
  765. private static final class ScopeRenderer extends DefaultListCellRenderer {
  766. @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
  767. if (value instanceof ScopeDescription) {
  768. ScopeDescription sd = (ScopeDescription) value;
  769. try {
  770. return super.getListCellRendererComponent(list, sd.getDisplayName(), index, isSelected, cellHasFocus);
  771. } finally {
  772. setIcon(sd.getIcon());
  773. }
  774. }
  775. return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
  776. }
  777. }
  778. private static class Separator implements Border {
  779. private Color fgColor;
  780. Separator(Color color) {
  781. fgColor = color;
  782. }
  783. public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
  784. Graphics gr = g.create();
  785. if (gr != null) {
  786. try {
  787. gr.translate(x, y);
  788. gr.setColor(fgColor);
  789. gr.drawLine(0, height - 1, width - 1, height - 1);
  790. } finally {
  791. gr.dispose();
  792. }
  793. }
  794. }
  795. public boolean isBorderOpaque() {
  796. return true;
  797. }
  798. public Insets getBorderInsets(Component c) {
  799. return new Insets(0, 0, 1, 0);
  800. }
  801. }
  802. private static final class AnalyzerAndWarning {
  803. private final AnalyzerFactory analyzer;
  804. private final WarningDescription wd;
  805. public AnalyzerAndWarning(AnalyzerFactory analyzer, WarningDescription wd) {
  806. this.analyzer = analyzer;
  807. this.wd = wd;
  808. }
  809. }
  810. public static final class DialogState {
  811. private final boolean configurationsSelected;
  812. private final String selectedAnalyzer;
  813. private final String selectedConfiguration;
  814. private final String selectedInspection;
  815. private DialogState(boolean configurationsSelected, String selectedAnalyzer, String selectedConfiguration, String selectedInspection) {
  816. this.configurationsSelected = configurationsSelected;
  817. this.selectedAnalyzer = selectedAnalyzer;
  818. this.selectedConfiguration = selectedConfiguration;
  819. this.selectedInspection = selectedInspection;
  820. }
  821. public void save() {
  822. Preferences prefs = NbPreferences.forModule(RunAnalysisPanel.class).node("RunAnalysisPanel");
  823. prefs.putBoolean("configurationsSelected", configurationsSelected);
  824. if (selectedAnalyzer != null)
  825. prefs.put("selectedAnalyzer", selectedAnalyzer);
  826. else
  827. prefs.remove("selectedAnalyzer");
  828. if (selectedConfiguration != null)
  829. prefs.put("selectedConfiguration", selectedConfiguration);
  830. else
  831. prefs.remove("selectedConfiguration");
  832. if (selectedInspection != null)
  833. prefs.put("selectedInspection", selectedInspection);
  834. else
  835. prefs.remove("selectedInspection");
  836. }
  837. private static DialogState load() {
  838. Preferences prefs = NbPreferences.forModule(RunAnalysisPanel.class).node("RunAnalysisPanel");
  839. return new DialogState(prefs.getBoolean("configurationsSelected", true),
  840. prefs.get("selectedAnalyzer", null),
  841. prefs.get("selectedConfiguration", null),
  842. prefs.get("selectedInspection", null));
  843. }
  844. public static DialogState from(WarningDescription wd) {
  845. return new DialogState(false, null, null, SPIAccessor.ACCESSOR.getWarningId(wd));
  846. }
  847. }
  848. public static class FutureWarnings {
  849. private Map<AnalyzerFactory, Map<String, WarningDescription>> result;
  850. public synchronized boolean isDone() {
  851. return result != null;
  852. }
  853. public synchronized Map<AnalyzerFactory, Map<String, WarningDescription>> get() {
  854. while (result == null) {
  855. try {
  856. wait();
  857. } catch (InterruptedException ex) {
  858. //Should not be happening, hopefully:
  859. Logger.getLogger(RunAnalysisPanel.class.getName()).log(Level.FINE, null, ex);
  860. }
  861. }
  862. return result;
  863. }
  864. synchronized void set(Map<AnalyzerFactory, Map<String, WarningDescription>> value) {
  865. result = value;
  866. notifyAll();
  867. }
  868. }
  869. }