| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.netbeans.modules.analysis; |
| |
| import java.awt.CardLayout; |
| import java.awt.Color; |
| import java.awt.Component; |
| import java.awt.Dimension; |
| import java.awt.Font; |
| import java.awt.Graphics; |
| import java.awt.GridBagConstraints; |
| import java.awt.Insets; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.KeyAdapter; |
| import java.awt.event.KeyEvent; |
| import java.beans.BeanInfo; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Set; |
| import java.util.TreeMap; |
| import java.util.TreeSet; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import java.util.prefs.Preferences; |
| import javax.swing.DefaultComboBoxModel; |
| import javax.swing.DefaultListCellRenderer; |
| import javax.swing.Icon; |
| import javax.swing.JButton; |
| import javax.swing.JComponent; |
| import javax.swing.JList; |
| import javax.swing.JPanel; |
| import javax.swing.SwingUtilities; |
| import javax.swing.UIManager; |
| import javax.swing.border.Border; |
| import javax.swing.border.EmptyBorder; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import org.netbeans.api.fileinfo.NonRecursiveFolder; |
| import org.netbeans.api.java.classpath.ClassPath; |
| import org.netbeans.api.progress.ProgressHandle; |
| import org.netbeans.api.progress.ProgressHandleFactory; |
| import org.netbeans.api.project.FileOwnerQuery; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ProjectInformation; |
| import org.netbeans.api.project.ProjectUtils; |
| import org.netbeans.api.project.SourceGroup; |
| import org.netbeans.api.project.ui.OpenProjects; |
| import org.netbeans.modules.analysis.spi.Analyzer.AnalyzerFactory; |
| import org.netbeans.modules.analysis.spi.Analyzer.Context; |
| import org.netbeans.modules.analysis.spi.Analyzer.MissingPlugin; |
| import org.netbeans.modules.analysis.spi.Analyzer.WarningDescription; |
| import org.netbeans.modules.analysis.ui.AdjustConfigurationPanel; |
| import org.netbeans.modules.analysis.ui.AdjustConfigurationPanel.ErrorListener; |
| import org.netbeans.modules.analysis.ui.ConfigurationsComboModel; |
| import org.netbeans.modules.refactoring.api.Scope; |
| import org.openide.DialogDescriptor; |
| import org.openide.DialogDisplayer; |
| import org.openide.NotificationLineSupport; |
| import org.openide.NotifyDescriptor; |
| import org.openide.filesystems.FileObject; |
| import org.openide.loaders.DataFolder; |
| import org.openide.loaders.DataObject; |
| import org.openide.loaders.DataObjectNotFoundException; |
| import org.openide.nodes.Node; |
| import org.openide.util.ImageUtilities; |
| import org.openide.util.Lookup; |
| import org.openide.util.LookupEvent; |
| import org.openide.util.LookupListener; |
| import org.openide.util.NbBundle.Messages; |
| import org.openide.util.NbPreferences; |
| import org.openide.util.RequestProcessor; |
| |
| /** |
| * |
| * @author lahvac |
| */ |
| public final class RunAnalysisPanel extends javax.swing.JPanel implements LookupListener { |
| |
| private static final String COMBO_PROTOTYPE = "999999999999999999999999999999999999"; |
| private static final RequestProcessor WORKER = new RequestProcessor(RunAnalysisPanel.class.getName(), 1, false, false); |
| private final JPanel progress; |
| private final RequiredPluginsPanel requiredPlugins; |
| //GuardedBy(AWT) |
| private Collection<? extends AnalyzerFactory> analyzers; |
| //GuardedBy(AWT) |
| private FutureWarnings analyzer2Warnings; |
| private final Lookup.Result<AnalyzerFactory> analyzersResult; |
| private final Map<String, AnalyzerAndWarning> warningId2Description = new HashMap<String, AnalyzerAndWarning>(); |
| private final JButton runAnalysis; |
| //GuardedBy(AWT) |
| private boolean inspectionsReady; |
| private boolean started; |
| |
| public RunAnalysisPanel(ProgressHandle handle, Lookup context, JButton runAnalysis) { |
| this(handle, context, runAnalysis, null); |
| } |
| |
| public RunAnalysisPanel(ProgressHandle handle, Lookup context, JButton runAnalysis, DialogState state) { |
| this.runAnalysis = runAnalysis; |
| this.analyzersResult = Lookup.getDefault().lookupResult(AnalyzerFactory.class); |
| this.analyzersResult.addLookupListener(this); |
| |
| initComponents(); |
| |
| List<ScopeDescription> scopes = new ArrayList<ScopeDescription>(); |
| Icon currentProjectIcon = null; |
| NonRecursiveFolder pack = context.lookup(NonRecursiveFolder.class); |
| FileObject currentFile = context.lookup(FileObject.class); |
| DataFolder folder = context.lookup(DataFolder.class); |
| |
| if (currentFile != null && currentFile.isData()) { |
| scopes.add(new FileScopeDescription(currentFile)); |
| } |
| |
| if (folder != null) { |
| scopes.add(new FolderScopeDescription(folder)); |
| } |
| |
| if (pack != null && currentFile == null) { |
| currentFile = pack.getFolder(); |
| } |
| |
| if (currentFile != null) { |
| Project p = FileOwnerQuery.getOwner(currentFile); |
| |
| if (p != null) { |
| ProjectInformation pi = ProjectUtils.getInformation(p); |
| |
| scopes.add(0, new CurrentProjectScopeDescription(p)); |
| currentProjectIcon = pi.getIcon(); |
| |
| if (pack == null) { |
| ClassPath bootCP = ClassPath.getClassPath(currentFile, ClassPath.BOOT); |
| |
| if (bootCP != null) { |
| final FileObject packFO = !currentFile.isFolder() ? currentFile.getParent() : currentFile; |
| pack = new NonRecursiveFolder() { |
| @Override public FileObject getFolder() { |
| return packFO; |
| } |
| }; |
| } |
| } |
| } |
| } else { |
| Project selected = context.lookup(Project.class); |
| |
| if (selected == null) { |
| SourceGroup sg = context.lookup(SourceGroup.class); |
| |
| if (sg != null) { |
| selected = FileOwnerQuery.getOwner(sg.getRootFolder()); |
| } |
| } |
| |
| if (selected == null) { |
| DataFolder df = context.lookup(DataFolder.class); |
| |
| if (df != null) { |
| selected = FileOwnerQuery.getOwner(df.getPrimaryFile()); |
| } |
| } |
| |
| if (selected != null) { |
| ProjectInformation pi = ProjectUtils.getInformation(selected); |
| |
| scopes.add(0, new CurrentProjectScopeDescription(selected)); |
| currentProjectIcon = pi.getIcon(); |
| } |
| } |
| |
| if (pack != null) { |
| ClassPath source = ClassPath.getClassPath(pack.getFolder(), ClassPath.SOURCE); |
| |
| if (source != null) { |
| String packName = source.getResourceName(pack.getFolder(), '.', false); |
| |
| scopes.add(1, new PackageScopeDescription(pack, packName)); |
| } |
| } |
| |
| scopes.add(0, new AllProjectsScopeDescription(currentProjectIcon)); |
| |
| scopeCombo.setModel(new DefaultComboBoxModel(scopes.toArray(new ScopeDescription[0]))); |
| scopeCombo.setRenderer(new ScopeRenderer()); |
| scopeCombo.setSelectedIndex(scopes.size() - 1); |
| |
| GridBagConstraints gridBagConstraints = new java.awt.GridBagConstraints(); |
| |
| gridBagConstraints.gridx = 0; |
| gridBagConstraints.gridy = 3; |
| gridBagConstraints.gridwidth = 4; |
| gridBagConstraints.gridheight = 1; |
| gridBagConstraints.weightx = 1; |
| gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; |
| gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); |
| progress = new JPanel(new CardLayout()); |
| progress.add(new JPanel(), "empty"); |
| progress.add(ProgressHandleFactory.createProgressComponent(handle), "progress"); |
| progress.add(requiredPlugins = new RequiredPluginsPanel(), "plugins"); |
| add(progress, gridBagConstraints); |
| ((CardLayout) progress.getLayout()).show(progress, "empty"); |
| |
| if (state == null) state = DialogState.load(); |
| updateConfigurations(state); |
| updateEnableDisable(); |
| |
| setBorder(new EmptyBorder(12, 12, 12, 12)); |
| |
| ConfigurationsManager.getDefault().addChangeListener(new ChangeListener() { |
| @Override public void stateChanged(ChangeEvent e) { |
| resultChanged(null); |
| } |
| }); |
| |
| configurationCombo.addActionListener(new ActionListener() { |
| Object currentItem = configurationCombo.getSelectedItem(); |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| Object tempItem = configurationCombo.getSelectedItem(); |
| if (tempItem instanceof String) { |
| configurationCombo.setSelectedItem(currentItem); |
| } else { |
| currentItem = tempItem; |
| updateEnableDisable(); |
| } |
| } |
| }); |
| |
| inspectionCombo.addActionListener(new ActionListener() { |
| Object currentItem = inspectionCombo.getSelectedItem(); |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| Object tempItem = inspectionCombo.getSelectedItem(); |
| if (!(tempItem instanceof AnalyzerAndWarning)) { |
| inspectionCombo.setSelectedItem(currentItem); |
| updatePlugins(); |
| } else { |
| currentItem = tempItem; |
| } |
| } |
| }); |
| |
| inspectionCombo.addKeyListener(new KeyAdapter() { |
| @Override |
| public void keyPressed(KeyEvent e) { |
| int direction = 1; |
| switch (e.getKeyCode()) { |
| case KeyEvent.VK_DOWN: |
| direction = 1; |
| break; |
| case KeyEvent.VK_UP: |
| direction = -1; |
| break; |
| } |
| int currentIndex = inspectionCombo.getSelectedIndex() + direction; |
| Object tempItem = inspectionCombo.getItemAt(currentIndex); |
| if (tempItem instanceof AnalyzerAndWarning) { |
| return; |
| } else { |
| currentIndex += direction; |
| } |
| Object nextItem = inspectionCombo.getItemAt(currentIndex); |
| while (!(nextItem instanceof AnalyzerAndWarning)) { |
| currentIndex += direction; |
| nextItem = inspectionCombo.getItemAt(currentIndex); |
| if (nextItem == null) { |
| return; |
| } |
| } |
| inspectionCombo.setSelectedItem((AnalyzerAndWarning) nextItem); |
| e.consume(); |
| } |
| }); |
| |
| if (state != null && state.scope != null) { |
| for (int i = 0; i < scopeCombo.getItemCount(); i++) { |
| ScopeDescription sd = (ScopeDescription)scopeCombo.getItemAt(i); |
| if (sd != null && sd.getId().equals(state.scope)) { |
| scopeCombo.setSelectedIndex(i); |
| break; |
| } |
| } |
| } |
| } |
| |
| void started() { |
| started = true; |
| |
| ((CardLayout) progress.getLayout()).show(progress, "progress"); |
| progress.invalidate(); |
| |
| //disable all elements in the dialog: |
| List<JComponent> todo = new LinkedList<JComponent>(); |
| |
| todo.add(this); |
| |
| while (!todo.isEmpty()) { |
| JComponent c = todo.remove(0); |
| |
| if (c == progress) continue; |
| |
| c.setEnabled(false); |
| |
| for (Component child : c.getComponents()) { |
| if (child instanceof JComponent) todo.add((JComponent) child); |
| } |
| } |
| } |
| |
| @Messages({"LBL_Predefined=Predefined", "LBL_Custom=Custom", "LBL_PleaseWait=Computing..."}) |
| public void updateConfigurations(final DialogState state) { |
| analyzers = analyzersResult.allInstances(); |
| |
| Object selectedConfiguration = null; |
| DefaultComboBoxModel configurationModel = new DefaultComboBoxModel(); |
| configurationModel.addElement(Bundle.LBL_Predefined()); |
| configurationModel.addElement(null); |
| |
| for (AnalyzerFactory analyzer : analyzers) { |
| if (SPIAccessor.ACCESSOR.getAnalyzerId(analyzer).equals(state.selectedAnalyzer)) { |
| selectedConfiguration = analyzer; |
| } |
| configurationModel.addElement(analyzer); |
| } |
| |
| configurationModel.addElement(Bundle.LBL_Custom()); |
| |
| for (Configuration c : ConfigurationsManager.getDefault().getConfigurations()) { |
| if (c.id().equals(state.selectedConfiguration)) { |
| selectedConfiguration = c; |
| } |
| configurationModel.addElement(c); |
| } |
| |
| configurationCombo.setModel(configurationModel); |
| configurationCombo.setSelectedItem(selectedConfiguration); |
| |
| configurationRadio.setSelected(state.configurationsSelected); |
| configurationCombo.setRenderer(new ConfigurationRenderer(true)); |
| |
| DefaultComboBoxModel inspectionModel = new DefaultComboBoxModel(); |
| |
| inspectionModel.addElement(Bundle.LBL_PleaseWait()); |
| |
| inspectionCombo.setModel(inspectionModel); |
| inspectionCombo.setRenderer(new InspectionRenderer()); |
| inspectionCombo.setSelectedItem(0); |
| singleInspectionRadio.setSelected(!state.configurationsSelected); |
| |
| updatePlugins(); |
| |
| final Collection<? extends AnalyzerFactory> analyzersCopy = new ArrayList<AnalyzerFactory>(analyzers); |
| |
| inspectionsReady = false; |
| analyzer2Warnings = new FutureWarnings(); |
| |
| WORKER.post(new Runnable() { |
| @Override public void run() { |
| final Map<AnalyzerFactory, Iterable<? extends WarningDescription>> analyzer2Warnings = new HashMap<AnalyzerFactory, Iterable<? extends WarningDescription>>(); |
| |
| for (AnalyzerFactory a : analyzersCopy) { |
| List<WarningDescription> warnings = new ArrayList<WarningDescription>(); |
| |
| for (WarningDescription wd : a.getWarnings()) { |
| warnings.add(wd); |
| } |
| |
| analyzer2Warnings.put(a, warnings); |
| } |
| |
| final Map<AnalyzerFactory, Map<String, WarningDescription>> analyzer2Id2DescriptionVal = computeAnalyzerId2Description(analyzer2Warnings); |
| |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override public void run() { |
| RunAnalysisPanel.this.analyzer2Warnings.set(analyzer2Id2DescriptionVal); |
| fillInspectionCombo(state, analyzer2Warnings); |
| inspectionsReady = true; |
| updatePlugins(); |
| } |
| }); |
| } |
| }); |
| } |
| |
| private void fillInspectionCombo(DialogState state, Map<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> analyzer2Warnings) { |
| DefaultComboBoxModel inspectionModel = new DefaultComboBoxModel(); |
| AnalyzerAndWarning firstInspection = null; |
| AnalyzerAndWarning preselectInspection = null; |
| |
| for (Entry<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> e : analyzer2Warnings.entrySet()) { |
| inspectionModel.addElement(SPIAccessor.ACCESSOR.getAnalyzerDisplayName(e.getKey())); |
| |
| Map<String, Collection<WarningDescription>> cat2Warnings = new TreeMap<String, Collection<WarningDescription>>(); |
| |
| for (WarningDescription wd : e.getValue()) { |
| String cat = SPIAccessor.ACCESSOR.getWarningCategoryDisplayName(wd); //TODO: should be based on the id rather than on the display name |
| Collection<WarningDescription> warnings = cat2Warnings.get(cat); |
| |
| if (warnings == null) { |
| cat2Warnings.put(cat, warnings = new TreeSet<WarningDescription>(new Comparator<WarningDescription>() { |
| @Override public int compare(WarningDescription o1, WarningDescription o2) { |
| return SPIAccessor.ACCESSOR.getWarningDisplayName(o1).compareToIgnoreCase(SPIAccessor.ACCESSOR.getWarningDisplayName(o2)); |
| } |
| })); |
| } |
| |
| warnings.add(wd); |
| } |
| |
| for (Entry<String, Collection<WarningDescription>> catE : cat2Warnings.entrySet()) { |
| inspectionModel.addElement(" " + catE.getKey()); |
| |
| for (WarningDescription wd : catE.getValue()) { |
| AnalyzerAndWarning aaw = new AnalyzerAndWarning(e.getKey(), wd); |
| inspectionModel.addElement(aaw); |
| warningId2Description.put(SPIAccessor.ACCESSOR.getWarningId(wd), aaw); |
| |
| if (firstInspection == null) firstInspection = aaw; |
| if (SPIAccessor.ACCESSOR.getWarningId(wd).equals(state.selectedInspection)) { |
| preselectInspection = aaw; |
| } |
| } |
| } |
| } |
| |
| inspectionCombo.setModel(inspectionModel); |
| inspectionCombo.setSelectedItem(preselectInspection != null ? preselectInspection : firstInspection); |
| |
| } |
| |
| private void updatePlugins() { |
| if (started) return ; |
| |
| Collection<? extends AnalyzerFactory> toRun; |
| |
| if (singleInspectionRadio.isSelected()) { |
| if (!inspectionsReady) { |
| runAnalysis.setEnabled(false); |
| return ; |
| } |
| |
| Object selectedInspection = inspectionCombo.getSelectedItem(); |
| |
| if (selectedInspection instanceof AnalyzerAndWarning) { |
| toRun = Collections.singleton(((AnalyzerAndWarning) selectedInspection).analyzer); |
| } else { |
| toRun = Collections.emptyList(); |
| } |
| } else { |
| if (!(configurationCombo.getSelectedItem() instanceof AnalyzerFactory)) { |
| toRun = analyzers; |
| } else { |
| toRun = Collections.singleton((AnalyzerFactory) configurationCombo.getSelectedItem()); |
| } |
| } |
| Set<MissingPlugin> plugins = new HashSet<MissingPlugin>(); |
| boolean someOk = false; |
| |
| for (AnalyzerFactory a : toRun) { |
| Configuration configuration = getConfiguration(); |
| Preferences settings = configuration != null ? configuration.getPreferences().node(SPIAccessor.ACCESSOR.getAnalyzerId(a)) : null; |
| Context ctx = SPIAccessor.ACCESSOR.createContext(getSelectedScope(new AtomicBoolean(false)), settings, null, null, -1, -1); |
| Collection<? extends MissingPlugin> req = a.requiredPlugins(ctx); |
| plugins.addAll(req); |
| someOk |= req.isEmpty(); |
| } |
| |
| if (plugins.isEmpty()) { |
| ((CardLayout) progress.getLayout()).show(progress, "empty"); |
| } else { |
| requiredPlugins.setRequiredPlugins(plugins, !someOk); |
| ((CardLayout) progress.getLayout()).show(progress, "plugins"); |
| } |
| |
| runAnalysis.setEnabled(someOk); |
| } |
| |
| public Scope getSelectedScope(AtomicBoolean cancel) { |
| return ((ScopeDescription) scopeCombo.getSelectedItem()).getScope(cancel); |
| } |
| |
| public AnalyzerFactory getSelectedAnalyzer() { |
| if (singleInspectionRadio.isSelected()) { |
| Object singleInspection = inspectionCombo.getSelectedItem(); |
| |
| if (singleInspection instanceof AnalyzerAndWarning) { |
| return ((AnalyzerAndWarning) singleInspection).analyzer; |
| } |
| |
| return null; |
| } |
| if (!(configurationCombo.getSelectedItem() instanceof AnalyzerFactory)) return null; |
| return (AnalyzerFactory) configurationCombo.getSelectedItem(); |
| } |
| |
| public Configuration getConfiguration() { |
| if (inspectionCombo.isEnabled()) return ConfigurationsManager.getDefault().getTemporaryConfiguration(); |
| Object selected = configurationCombo.getSelectedItem(); |
| |
| if (selected instanceof Configuration) return (Configuration) selected; |
| else return null; |
| } |
| |
| public Collection<? extends AnalyzerFactory> getAnalyzers() { |
| return analyzers; |
| } |
| |
| /** |
| * This method is called from within the constructor to initialize the form. |
| * WARNING: Do NOT modify this code. The content of this method is always |
| * regenerated by the Form Editor. |
| */ |
| @SuppressWarnings("unchecked") |
| // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents |
| private void initComponents() { |
| java.awt.GridBagConstraints gridBagConstraints; |
| |
| radioButtons = new javax.swing.ButtonGroup(); |
| javax.swing.JLabel jLabel1 = new javax.swing.JLabel(); |
| scopeCombo = new javax.swing.JComboBox(); |
| javax.swing.JLabel jLabel2 = new javax.swing.JLabel(); |
| configurationCombo = new javax.swing.JComboBox(); |
| manage = new javax.swing.JButton(); |
| configurationRadio = new javax.swing.JRadioButton(); |
| singleInspectionRadio = new javax.swing.JRadioButton(); |
| inspectionCombo = new javax.swing.JComboBox(); |
| browse = new javax.swing.JButton(); |
| javax.swing.JPanel emptyPanel = new javax.swing.JPanel(); |
| |
| setLayout(new java.awt.GridBagLayout()); |
| |
| org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.jLabel1.text")); // NOI18N |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 0; |
| gridBagConstraints.gridy = 0; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING; |
| add(jLabel1, gridBagConstraints); |
| |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 1; |
| gridBagConstraints.gridy = 0; |
| gridBagConstraints.gridwidth = 3; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING; |
| gridBagConstraints.weightx = 1.0; |
| gridBagConstraints.insets = new java.awt.Insets(0, 12, 0, 0); |
| add(scopeCombo, gridBagConstraints); |
| |
| org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.jLabel2.text")); // NOI18N |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 0; |
| gridBagConstraints.gridy = 1; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING; |
| gridBagConstraints.insets = new java.awt.Insets(12, 0, 0, 0); |
| add(jLabel2, gridBagConstraints); |
| |
| configurationCombo.setPrototypeDisplayValue(COMBO_PROTOTYPE); |
| configurationCombo.addActionListener(new java.awt.event.ActionListener() { |
| public void actionPerformed(java.awt.event.ActionEvent evt) { |
| configurationComboActionPerformed(evt); |
| } |
| }); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 2; |
| gridBagConstraints.gridy = 1; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.ABOVE_BASELINE_LEADING; |
| gridBagConstraints.weightx = 1.0; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); |
| add(configurationCombo, gridBagConstraints); |
| |
| org.openide.awt.Mnemonics.setLocalizedText(manage, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.manage.text")); // NOI18N |
| manage.addActionListener(new java.awt.event.ActionListener() { |
| public void actionPerformed(java.awt.event.ActionEvent evt) { |
| manageActionPerformed(evt); |
| } |
| }); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 3; |
| gridBagConstraints.gridy = 1; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); |
| add(manage, gridBagConstraints); |
| |
| radioButtons.add(configurationRadio); |
| org.openide.awt.Mnemonics.setLocalizedText(configurationRadio, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.configurationRadio.text")); // NOI18N |
| configurationRadio.addActionListener(new java.awt.event.ActionListener() { |
| public void actionPerformed(java.awt.event.ActionEvent evt) { |
| configurationRadioActionPerformed(evt); |
| } |
| }); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 1; |
| gridBagConstraints.gridy = 1; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); |
| add(configurationRadio, gridBagConstraints); |
| |
| radioButtons.add(singleInspectionRadio); |
| org.openide.awt.Mnemonics.setLocalizedText(singleInspectionRadio, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.singleInspectionRadio.text")); // NOI18N |
| singleInspectionRadio.addActionListener(new java.awt.event.ActionListener() { |
| public void actionPerformed(java.awt.event.ActionEvent evt) { |
| singleInspectionRadioActionPerformed(evt); |
| } |
| }); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 1; |
| gridBagConstraints.gridy = 2; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE_LEADING; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); |
| add(singleInspectionRadio, gridBagConstraints); |
| |
| inspectionCombo.setPrototypeDisplayValue(COMBO_PROTOTYPE); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 2; |
| gridBagConstraints.gridy = 2; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE; |
| gridBagConstraints.weightx = 1.0; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); |
| add(inspectionCombo, gridBagConstraints); |
| |
| org.openide.awt.Mnemonics.setLocalizedText(browse, org.openide.util.NbBundle.getMessage(RunAnalysisPanel.class, "RunAnalysisPanel.browse.text")); // NOI18N |
| browse.addActionListener(new java.awt.event.ActionListener() { |
| public void actionPerformed(java.awt.event.ActionEvent evt) { |
| browseActionPerformed(evt); |
| } |
| }); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridx = 3; |
| gridBagConstraints.gridy = 2; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL; |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.BASELINE; |
| gridBagConstraints.insets = new java.awt.Insets(12, 12, 0, 0); |
| add(browse, gridBagConstraints); |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.gridy = 3; |
| gridBagConstraints.gridwidth = 4; |
| gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; |
| gridBagConstraints.weighty = 1.0; |
| add(emptyPanel, gridBagConstraints); |
| }// </editor-fold>//GEN-END:initComponents |
| |
| private void configurationComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configurationComboActionPerformed |
| updatePlugins(); |
| }//GEN-LAST:event_configurationComboActionPerformed |
| |
| private AdjustConfigurationPanel showConfigurationPanel(AnalyzerFactory preselectedAnalyzer, String preselected, Configuration configurationToSelect) { |
| final NotificationLineSupport[] nls = new NotificationLineSupport[1]; |
| final DialogDescriptor[] dd = new DialogDescriptor[1]; |
| ErrorListener errorListener = new ErrorListener() { |
| @Override public void setError(String error) { |
| nls[0].setErrorMessage(error); |
| dd[0].setValid(error == null); |
| } |
| }; |
| AdjustConfigurationPanel panel = new AdjustConfigurationPanel(analyzers, preselectedAnalyzer, preselected, configurationToSelect, errorListener); |
| panel.setPreferredSize(new Dimension(700, 300)); |
| DialogDescriptor nd = new DialogDescriptor(panel, Bundle.LBL_Configurations(), true, NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.OK_OPTION, null); |
| |
| nls[0] = nd.createNotificationLineSupport(); |
| dd[0] = nd; |
| |
| if (DialogDisplayer.getDefault().notify(nd) == NotifyDescriptor.OK_OPTION) { |
| return panel; |
| } |
| |
| return null; |
| } |
| |
| @Messages("LBL_Configurations=Configurations") |
| private void manageActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_manageActionPerformed |
| AdjustConfigurationPanel panel = showConfigurationPanel(null, null, (Configuration) configurationCombo.getSelectedItem()); |
| if (panel != null) { |
| panel.save(); |
| configurationCombo.setSelectedItem(panel.getSelectedConfiguration()); |
| } |
| }//GEN-LAST:event_manageActionPerformed |
| |
| private void configurationRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_configurationRadioActionPerformed |
| updateEnableDisable(); |
| }//GEN-LAST:event_configurationRadioActionPerformed |
| |
| private void singleInspectionRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_singleInspectionRadioActionPerformed |
| updateEnableDisable(); |
| }//GEN-LAST:event_singleInspectionRadioActionPerformed |
| |
| @Messages("LBL_Browse=Browse Inspections") |
| private void browseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseActionPerformed |
| Object selectedInspection = inspectionCombo.getSelectedItem(); |
| AnalyzerFactory analyzerToSelect; |
| String warningToSelect; |
| |
| if (selectedInspection instanceof AnalyzerAndWarning) { |
| analyzerToSelect = ((AnalyzerAndWarning) selectedInspection).analyzer; |
| warningToSelect = SPIAccessor.ACCESSOR.getWarningId(((AnalyzerAndWarning) selectedInspection).wd); |
| } else { |
| analyzerToSelect = null; |
| warningToSelect = ""; |
| } |
| |
| AdjustConfigurationPanel panel = showConfigurationPanel(analyzerToSelect, warningToSelect, null); |
| |
| if (panel != null) { |
| inspectionCombo.setSelectedItem(warningId2Description.get(panel.getIdToRun())); |
| } |
| }//GEN-LAST:event_browseActionPerformed |
| |
| // Variables declaration - do not modify//GEN-BEGIN:variables |
| private javax.swing.JButton browse; |
| private javax.swing.JComboBox configurationCombo; |
| private javax.swing.JRadioButton configurationRadio; |
| private javax.swing.JComboBox inspectionCombo; |
| private javax.swing.JButton manage; |
| private javax.swing.ButtonGroup radioButtons; |
| private javax.swing.JComboBox scopeCombo; |
| private javax.swing.JRadioButton singleInspectionRadio; |
| // End of variables declaration//GEN-END:variables |
| |
| private void updateEnableDisable() { |
| if (started) return ; |
| |
| boolean configuration = configurationRadio.isSelected(); |
| |
| configurationCombo.setEnabled(configuration); |
| manage.setEnabled(configuration && configurationCombo.getSelectedItem() instanceof Configuration); |
| inspectionCombo.setEnabled(!configuration); |
| browse.setEnabled(!configuration); |
| |
| updatePlugins(); |
| } |
| |
| String getSingleWarningId() { |
| return inspectionCombo.isEnabled() ? SPIAccessor.ACCESSOR.getWarningId(((AnalyzerAndWarning) inspectionCombo.getSelectedItem()).wd) : null; |
| } |
| |
| @Override |
| public void resultChanged(LookupEvent ev) { |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override public void run() { |
| updateConfigurations(getDialogState()); |
| } |
| }); |
| } |
| |
| public DialogState getDialogState() { |
| Object selectedConfiguration = configurationCombo.getSelectedItem(); |
| Object selectedInspection = inspectionCombo.getSelectedItem(); |
| return new DialogState(configurationRadio.isSelected(), |
| selectedConfiguration instanceof AnalyzerFactory ? SPIAccessor.ACCESSOR.getAnalyzerId((AnalyzerFactory) selectedConfiguration) : null, |
| selectedConfiguration instanceof Configuration ? ((Configuration) selectedConfiguration).id() : null, |
| selectedInspection instanceof AnalyzerAndWarning ? SPIAccessor.ACCESSOR.getWarningId(((AnalyzerAndWarning) selectedInspection).wd) : null, |
| ((ScopeDescription) scopeCombo.getSelectedItem()).getId()); |
| } |
| |
| FutureWarnings getAnalyzerId2Description() { |
| return analyzer2Warnings; |
| } |
| |
| private static Map<AnalyzerFactory, Map<String, WarningDescription>> computeAnalyzerId2Description(Map<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> analyzer2Warnings) { |
| Map<AnalyzerFactory, Map<String, WarningDescription>> result = new HashMap<AnalyzerFactory, Map<String, WarningDescription>>(); |
| |
| for (Entry<? extends AnalyzerFactory, Iterable<? extends WarningDescription>> e : analyzer2Warnings.entrySet()) { |
| Map<String, WarningDescription> perAnalyzer = new HashMap<String, WarningDescription>(); |
| |
| result.put(e.getKey(), perAnalyzer); |
| |
| for (WarningDescription wd : e.getValue()) { |
| perAnalyzer.put(SPIAccessor.ACCESSOR.getWarningId(wd), wd); |
| } |
| } |
| |
| return result; |
| } |
| |
| public static final class ConfigurationRenderer extends DefaultListCellRenderer { |
| |
| private final boolean indent; |
| |
| public ConfigurationRenderer(boolean indent) { |
| this.indent = indent; |
| } |
| |
| @Messages({"LBL_RunAllAnalyzers=All Analyzers", "# {0} - the analyzer that should be run", "LBL_RunAnalyzer={0}"}) |
| @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
| if (value == null) { |
| value = Bundle.LBL_RunAllAnalyzers(); |
| } else if (value instanceof AnalyzerFactory) { |
| value = Bundle.LBL_RunAnalyzer(SPIAccessor.ACCESSOR.getAnalyzerDisplayName((AnalyzerFactory) value)); |
| } else if (value instanceof Configuration) { |
| value = ((Configuration) value).getDisplayName(); |
| } else if (value instanceof String) { |
| setFont(getFont().deriveFont(Font.ITALIC)); |
| setText((String) value); |
| setEnabled(false); |
| setBackground(list.getBackground()); |
| setForeground(UIManager.getColor("Label.disabledForeground")); |
| |
| return this; |
| } |
| |
| if (index == list.getModel().getSize()-5 && list.getModel() instanceof ConfigurationsComboModel && ((ConfigurationsComboModel) list.getModel()).canModify()) { |
| setBorder(new Separator(list.getForeground())); |
| } else { |
| setBorder(null); |
| } |
| |
| return super.getListCellRendererComponent(list, (indent ? " " : "") + value, index, isSelected, cellHasFocus); |
| } |
| } |
| |
| private static final class InspectionRenderer extends DefaultListCellRenderer { |
| |
| @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
| if (value instanceof AnalyzerAndWarning) { |
| value = " " + SPIAccessor.ACCESSOR.getWarningDisplayName(((AnalyzerAndWarning) value).wd); |
| } else if (value instanceof String) { |
| setFont(getFont().deriveFont(Font.ITALIC)); |
| setText((String) value); |
| setEnabled(false); |
| setBackground(list.getBackground()); |
| setForeground(UIManager.getColor("Label.disabledForeground")); |
| |
| return this; |
| } |
| |
| return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
| } |
| } |
| |
| private interface ScopeDescription { |
| public String getDisplayName(); |
| public Icon getIcon(); |
| public Scope getScope(AtomicBoolean cancel); |
| public String getId(); |
| } |
| |
| private static final class AllProjectsScopeDescription implements ScopeDescription { |
| private final Icon icon; |
| public AllProjectsScopeDescription(Icon icon) { |
| this.icon = icon; |
| } |
| @Override |
| @Messages("DN_OpenProjects=Open Projects") |
| public String getDisplayName() { |
| return Bundle.DN_OpenProjects(); |
| } |
| @Override |
| public Icon getIcon() { |
| return icon; |
| } |
| |
| @Override |
| public Scope getScope(AtomicBoolean cancel) { |
| Map<Project, Map<FileObject, ClassPath>> projects2RegisteredContent = RunAnalysis.projects2RegisteredContent(cancel); |
| |
| if (cancel.get()) return null; |
| |
| Scope target = Scope.create(null, null, null); |
| |
| for (Project p : OpenProjects.getDefault().getOpenProjects()) { |
| if (cancel.get()) return null; |
| target = RunAnalysis.addProjectToScope(p, target, cancel, projects2RegisteredContent); |
| } |
| |
| return target; |
| } |
| |
| public String getId() { |
| return "*allProjects"; // NOI18N |
| } |
| } |
| |
| private static final class CurrentProjectScopeDescription implements ScopeDescription { |
| private final Project project; |
| public CurrentProjectScopeDescription(Project project) { |
| this.project = project; |
| } |
| @Override |
| @Messages({"# {0} - project display name", "DN_CurrentProject=Current Project ({0})"}) |
| public String getDisplayName() { |
| return Bundle.DN_CurrentProject(ProjectUtils.getInformation(project).getDisplayName()); |
| } |
| @Override |
| public Icon getIcon() { |
| return ProjectUtils.getInformation(project).getIcon(); |
| } |
| |
| @Override |
| public Scope getScope(AtomicBoolean cancel) { |
| Map<Project, Map<FileObject, ClassPath>> projects2RegisteredContent = RunAnalysis.projects2RegisteredContent(cancel); |
| |
| if (cancel.get()) return null; |
| |
| return RunAnalysis.addProjectToScope(project, Scope.create(null, null, null), cancel, projects2RegisteredContent); |
| } |
| |
| public String getId() { |
| return "*currentProject"; // NOI18N |
| } |
| } |
| |
| private static final class PackageScopeDescription implements ScopeDescription { |
| private final NonRecursiveFolder pack; |
| private final String packName; |
| public PackageScopeDescription(NonRecursiveFolder pack, String packName) { |
| this.pack = pack; |
| this.packName = packName; |
| } |
| @Override |
| @Messages({"# {0} - package display name", "DN_CurrentPackage=Current Package ({0})"}) |
| public String getDisplayName() { |
| return Bundle.DN_CurrentPackage(packName); |
| } |
| @Override |
| public Icon getIcon() { |
| return ImageUtilities.loadImageIcon("org/netbeans/modules/analysis/ui/resources/package.gif", false); |
| } |
| |
| @Override |
| public Scope getScope(AtomicBoolean cancel) { |
| return Scope.create(null, Collections.singletonList(pack), null); |
| } |
| |
| public String getId() { |
| return "*currentPackage"; // NOI18N |
| } |
| } |
| |
| private static final class FolderScopeDescription implements ScopeDescription { |
| private final DataFolder folder; |
| public FolderScopeDescription(DataFolder folder) { |
| this.folder = folder; |
| } |
| @Override |
| @Messages({"# {0} - folder display name", "DN_CurrentFolder=Current Folder ({0})"}) |
| public String getDisplayName() { |
| return Bundle.DN_CurrentFolder(folder.getName()); |
| } |
| @Override |
| public Icon getIcon() { |
| return ImageUtilities.image2Icon(folder.getNodeDelegate().getIcon(1)); |
| } |
| |
| @Override |
| public Scope getScope(AtomicBoolean cancel) { |
| return Scope.create(null, null, folder.files()); |
| } |
| |
| public String getId() { |
| return "*currentFolder"; // NOI18N |
| } |
| } |
| |
| private static final class FileScopeDescription implements ScopeDescription { |
| private static final Logger LOG = Logger.getLogger(FileScopeDescription.class.getName()); |
| private final FileObject file; |
| public FileScopeDescription(FileObject file) { |
| this.file = file; |
| } |
| @Override |
| @Messages({"# {0} - file display name", "DN_CurrentFile=Current File ({0})"}) |
| public String getDisplayName() { |
| return Bundle.DN_CurrentFile(file.getNameExt()); |
| } |
| @Override |
| public Icon getIcon() { |
| try { |
| DataObject d = DataObject.find(file); |
| Node n = d.getNodeDelegate(); |
| return ImageUtilities.image2Icon(n.getIcon(BeanInfo.ICON_COLOR_16x16)); |
| } catch (DataObjectNotFoundException ex) { |
| LOG.log(Level.FINE, null, ex); |
| return null; |
| } |
| } |
| |
| @Override |
| public Scope getScope(AtomicBoolean cancel) { |
| return Scope.create(null, null, Collections.singletonList(file)); |
| } |
| |
| public String getId() { |
| return "*currentFile"; |
| } |
| } |
| |
| private static final class ScopeRenderer extends DefaultListCellRenderer { |
| |
| @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { |
| if (value instanceof ScopeDescription) { |
| ScopeDescription sd = (ScopeDescription) value; |
| |
| try { |
| return super.getListCellRendererComponent(list, sd.getDisplayName(), index, isSelected, cellHasFocus); |
| } finally { |
| setIcon(sd.getIcon()); |
| } |
| } |
| |
| return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); |
| } |
| } |
| |
| private static class Separator implements Border { |
| |
| private Color fgColor; |
| |
| Separator(Color color) { |
| fgColor = color; |
| } |
| |
| public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { |
| Graphics gr = g.create(); |
| if (gr != null) { |
| try { |
| gr.translate(x, y); |
| gr.setColor(fgColor); |
| gr.drawLine(0, height - 1, width - 1, height - 1); |
| } finally { |
| gr.dispose(); |
| } |
| } |
| } |
| |
| public boolean isBorderOpaque() { |
| return true; |
| } |
| |
| public Insets getBorderInsets(Component c) { |
| return new Insets(0, 0, 1, 0); |
| } |
| } |
| |
| private static final class AnalyzerAndWarning { |
| private final AnalyzerFactory analyzer; |
| private final WarningDescription wd; |
| public AnalyzerAndWarning(AnalyzerFactory analyzer, WarningDescription wd) { |
| this.analyzer = analyzer; |
| this.wd = wd; |
| } |
| } |
| |
| public static final class DialogState { |
| private final boolean configurationsSelected; |
| private final String selectedAnalyzer; |
| private final String selectedConfiguration; |
| private final String selectedInspection; |
| private final String scope; |
| |
| private DialogState(boolean configurationsSelected, String selectedAnalyzer, String selectedConfiguration, String selectedInspection, String scope) { |
| this.configurationsSelected = configurationsSelected; |
| this.selectedAnalyzer = selectedAnalyzer; |
| this.selectedConfiguration = selectedConfiguration; |
| this.selectedInspection = selectedInspection; |
| this.scope = scope; |
| } |
| |
| public void save() { |
| Preferences prefs = NbPreferences.forModule(RunAnalysisPanel.class).node("RunAnalysisPanel"); |
| |
| prefs.putBoolean("configurationsSelected", configurationsSelected); |
| if (selectedAnalyzer != null) |
| prefs.put("selectedAnalyzer", selectedAnalyzer); |
| else |
| prefs.remove("selectedAnalyzer"); |
| if (selectedConfiguration != null) |
| prefs.put("selectedConfiguration", selectedConfiguration); |
| else |
| prefs.remove("selectedConfiguration"); |
| if (selectedInspection != null) |
| prefs.put("selectedInspection", selectedInspection); |
| else |
| prefs.remove("selectedInspection"); |
| } |
| |
| private static DialogState load() { |
| Preferences prefs = NbPreferences.forModule(RunAnalysisPanel.class).node("RunAnalysisPanel"); |
| return new DialogState(prefs.getBoolean("configurationsSelected", true), |
| prefs.get("selectedAnalyzer", null), |
| prefs.get("selectedConfiguration", null), |
| prefs.get("selectedInspection", null), |
| null); |
| } |
| |
| public static DialogState from(WarningDescription wd) { |
| return new DialogState(false, null, null, SPIAccessor.ACCESSOR.getWarningId(wd), null); |
| } |
| } |
| |
| public static class FutureWarnings { |
| private Map<AnalyzerFactory, Map<String, WarningDescription>> result; |
| public synchronized boolean isDone() { |
| return result != null; |
| } |
| public synchronized Map<AnalyzerFactory, Map<String, WarningDescription>> get() { |
| while (result == null) { |
| try { |
| wait(); |
| } catch (InterruptedException ex) { |
| //Should not be happening, hopefully: |
| Logger.getLogger(RunAnalysisPanel.class.getName()).log(Level.FINE, null, ex); |
| } |
| } |
| return result; |
| } |
| synchronized void set(Map<AnalyzerFactory, Map<String, WarningDescription>> value) { |
| result = value; |
| notifyAll(); |
| } |
| } |
| } |