| /* |
| * 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.maven.nodes; |
| |
| import java.awt.BorderLayout; |
| import java.awt.Color; |
| import java.awt.Image; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.FocusAdapter; |
| import java.awt.event.FocusEvent; |
| import java.beans.PropertyChangeEvent; |
| import java.beans.PropertyChangeListener; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| import javax.swing.AbstractAction; |
| import javax.swing.Action; |
| import javax.swing.JButton; |
| import javax.swing.JPanel; |
| import javax.swing.SwingUtilities; |
| import javax.swing.UIManager; |
| import javax.swing.border.Border; |
| import javax.swing.border.LineBorder; |
| import javax.swing.event.AncestorEvent; |
| import javax.swing.event.AncestorListener; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.event.DocumentEvent; |
| import javax.swing.event.DocumentListener; |
| import javax.swing.text.BadLocationException; |
| import javax.swing.text.Document; |
| import javax.swing.tree.TreeSelectionModel; |
| import org.apache.lucene.search.BooleanQuery; |
| import org.apache.maven.model.Dependency; |
| import org.apache.maven.model.DependencyManagement; |
| import org.apache.maven.project.MavenProject; |
| import org.apache.maven.project.ProjectBuildingException; |
| import org.netbeans.api.annotations.common.CheckForNull; |
| import org.netbeans.api.annotations.common.StaticResource; |
| import org.netbeans.api.project.Project; |
| import org.netbeans.api.project.ui.OpenProjects; |
| import org.netbeans.modules.maven.NbMavenProjectImpl; |
| import org.netbeans.modules.maven.TextValueCompleter; |
| import org.netbeans.modules.maven.api.NbMavenProject; |
| import org.netbeans.modules.maven.api.customizer.support.DelayedDocumentChangeListener; |
| import org.netbeans.modules.maven.embedder.EmbedderFactory; |
| import org.netbeans.modules.maven.indexer.api.NBVersionInfo; |
| import org.netbeans.modules.maven.indexer.api.QueryField; |
| import org.netbeans.modules.maven.indexer.api.RepositoryPreferences; |
| import org.netbeans.modules.maven.indexer.api.RepositoryQueries; |
| import org.netbeans.modules.maven.indexer.api.RepositoryQueries.Result; |
| import static org.netbeans.modules.maven.nodes.Bundle.*; |
| import org.netbeans.modules.maven.spi.nodes.MavenNodeFactory; |
| import org.netbeans.spi.project.ui.LogicalViewProvider; |
| import org.openide.DialogDescriptor; |
| import org.openide.DialogDisplayer; |
| import org.openide.NotificationLineSupport; |
| import org.openide.explorer.ExplorerManager; |
| import org.openide.explorer.view.BeanTreeView; |
| import org.openide.nodes.AbstractNode; |
| import org.openide.nodes.Children; |
| import org.openide.nodes.FilterNode; |
| import org.openide.nodes.Node; |
| import org.openide.util.ContextAwareAction; |
| import org.openide.util.Exceptions; |
| import org.openide.util.ImageUtilities; |
| import org.openide.util.Lookup; |
| import org.openide.util.NbBundle; |
| import org.openide.util.NbBundle.Messages; |
| import org.openide.util.RequestProcessor; |
| import org.openide.util.Task; |
| import org.openide.util.TaskListener; |
| import org.openide.util.lookup.AbstractLookup; |
| import org.openide.util.lookup.InstanceContent; |
| |
| /** |
| * @author mkleint |
| */ |
| public class AddDependencyPanel extends javax.swing.JPanel { |
| private static final @StaticResource String EMPTY_ICON = "org/netbeans/modules/maven/resources/empty.png"; |
| private static final @StaticResource String WAIT_ICON = "org/netbeans/modules/maven/resources/wait.gif"; |
| |
| /** |
| * Shows the Add Dependency dialog. |
| * @param prj a project to add a dependency to |
| * @param showDepMan true to show the dependency management panel |
| * @param selectedScope an initial scope selection (such as {@code compile}) |
| * @return groupId + artifactId + version + scope + type + classifier, or null if canceled |
| */ |
| @Messages("TIT_Add_Library=Add Dependency") |
| public static @CheckForNull String[] show(Project prj, boolean showDepMan, String selectedScope) { |
| NbMavenProject nbproj = prj.getLookup().lookup(NbMavenProject.class); |
| AddDependencyPanel pnl = new AddDependencyPanel(nbproj.getMavenProject(), showDepMan, prj); |
| pnl.getAccessibleContext().setAccessibleDescription(TIT_Add_Library()); |
| pnl.setSelectedScope(selectedScope); |
| DialogDescriptor dd = new DialogDescriptor(pnl, TIT_Add_Library()); |
| dd.setClosingOptions(new Object[] { |
| pnl.getOkButton(), |
| DialogDescriptor.CANCEL_OPTION |
| }); |
| dd.setOptions(new Object[] { |
| pnl.getOkButton(), |
| DialogDescriptor.CANCEL_OPTION |
| }); |
| pnl.attachDialogDisplayer(dd); |
| Object ret = DialogDisplayer.getDefault().notify(dd); |
| if (pnl.getOkButton() == ret) { |
| return new String[] { |
| pnl.getGroupId(), |
| pnl.getArtifactId(), |
| pnl.getVersion(), |
| pnl.getScope(), |
| pnl.getType(), |
| pnl.getClassifier() |
| }; |
| } |
| return null; |
| } |
| |
| private MavenProject project; |
| private Project nbProject; |
| |
| private final TextValueCompleter groupCompleter; |
| private final TextValueCompleter artifactCompleter; |
| private final TextValueCompleter versionCompleter; |
| private final JButton okButton; |
| private final QueryPanel queryPanel; |
| private DMListPanel artifactList; |
| |
| private Color defaultVersionC; |
| |
| private static final RequestProcessor RP = new RequestProcessor(AddDependencyPanel.class.getName(), 5); |
| private static final RequestProcessor RPofOpenListPanel = new RequestProcessor(AddDependencyPanel.OpenListPanel.class.getName(), 1); |
| private static final RequestProcessor RPofDMListPanel = new RequestProcessor(AddDependencyPanel.DMListPanel.class.getName(), 1); |
| private static final RequestProcessor RPofQueryPanel = new RequestProcessor(AddDependencyPanel.QueryPanel.class.getName(), 10); |
| |
| private NotificationLineSupport nls; |
| |
| @Messages("BTN_OK=Add") |
| private AddDependencyPanel(MavenProject mavenProject, boolean showDepMan, Project prj) { |
| this.project = mavenProject; |
| this.nbProject = prj; |
| initComponents(); |
| groupCompleter = new TextValueCompleter(Collections.<String>emptyList(), txtGroupId); |
| artifactCompleter = new TextValueCompleter(Collections.<String>emptyList(), txtArtifactId); |
| versionCompleter = new TextValueCompleter(Collections.<String>emptyList(), txtVersion); |
| txtGroupId.addFocusListener(new FocusAdapter() { |
| @Override |
| public void focusLost(FocusEvent e) { |
| final String groupId = txtGroupId.getText().trim(); |
| if (groupId.length() > 0) { |
| artifactCompleter.setLoading(true); |
| RP.post(new Runnable() { |
| @Override |
| public void run() { |
| populateArtifact(groupId); |
| } |
| }); |
| } |
| } |
| }); |
| |
| txtArtifactId.addFocusListener(new FocusAdapter() { |
| @Override |
| public void focusLost(FocusEvent e) { |
| final String groupId = txtGroupId.getText().trim(); |
| final String artifactId = txtArtifactId.getText().trim(); |
| if (groupId.length() > 0 && artifactId.length() > 0) { |
| versionCompleter.setLoading(true); |
| RP.post(new Runnable() { |
| @Override |
| public void run() { |
| populateVersion(groupId, artifactId); |
| } |
| }); |
| } |
| } |
| }); |
| |
| okButton = new JButton(BTN_OK()); |
| |
| DocumentListener docList = new DocumentListener() { |
| |
| @Override |
| public void changedUpdate(DocumentEvent e) { |
| checkValidState(); |
| } |
| |
| @Override |
| public void insertUpdate(DocumentEvent e) { |
| checkValidState(); |
| } |
| |
| @Override |
| public void removeUpdate(DocumentEvent e) { |
| checkValidState(); |
| } |
| }; |
| txtGroupId.getDocument().addDocumentListener(docList); |
| txtVersion.getDocument().addDocumentListener(docList); |
| txtArtifactId.getDocument().addDocumentListener(docList); |
| checkValidState(); |
| groupCompleter.setLoading(true); |
| RP.post(new Runnable() { |
| @Override |
| public void run() { |
| Result<String> res = populateGroupId(); |
| if (res.isPartial()) { |
| //we will ignore any rare occurances of repository being added after the groupId result is |
| // processed.. this is the only way of ensuring that the completion gets refreshed. |
| res.waitForSkipped(); |
| populateGroupId(); |
| final String[] vals = new String[2]; |
| try { |
| SwingUtilities.invokeAndWait(new Runnable() { |
| @Override |
| public void run() { |
| vals[0] = txtGroupId.getText().trim(); |
| vals[1] = txtArtifactId.getText().trim(); |
| } |
| }); |
| if (vals[0] != null && vals[0].length() > 0) { |
| populateArtifact(vals[0]); |
| if (vals[1] != null && vals[1].length() > 0) { |
| populateVersion(vals[0], vals[1]); |
| } |
| } |
| } catch (InterruptedException ex) { |
| Exceptions.printStackTrace(ex); |
| } catch (InvocationTargetException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| } |
| } |
| }); |
| |
| queryPanel = new QueryPanel(); |
| resultsPanel.add(queryPanel, BorderLayout.CENTER); |
| |
| searchField.getDocument().addDocumentListener( |
| DelayedDocumentChangeListener.create( |
| searchField.getDocument(), queryPanel, 500)); |
| |
| /*searchField.getDocument().addDocumentListener(new DocumentListener() { |
| |
| public void insertUpdate(DocumentEvent e) { |
| queryPanel.maybeFind(searchField.getText()); |
| } |
| |
| public void removeUpdate(DocumentEvent e) { |
| queryPanel.maybeFind(searchField.getText()); |
| } |
| |
| public void changedUpdate(DocumentEvent e) { |
| queryPanel.maybeFind(searchField.getText()); |
| } |
| });*/ |
| |
| defaultVersionC = txtVersion.getForeground(); |
| if (showDepMan) { |
| artifactList = new DMListPanel(project); |
| artifactPanel.add(artifactList, BorderLayout.CENTER); |
| } else { |
| tabPane.setEnabledAt(2, false); |
| } |
| chkNbOnly.setVisible(false); |
| String packaging = prj.getLookup().lookup(NbMavenProject.class).getPackagingType(); |
| if (NbMavenProject.TYPE_NBM.equals(packaging) || NbMavenProject.TYPE_NBM_APPLICATION.equals(packaging)) { |
| chkNbOnly.setVisible(true); |
| chkNbOnly.setSelected(true); |
| } |
| |
| pnlOpenProjects.add(new OpenListPanel(prj), BorderLayout.CENTER); |
| |
| } |
| |
| private JButton getOkButton() { |
| return okButton; |
| } |
| |
| private String getGroupId() { |
| return txtGroupId.getText().trim(); |
| } |
| |
| private String getArtifactId() { |
| return txtArtifactId.getText().trim(); |
| } |
| |
| private String getVersion() { |
| String v = txtVersion.getText().trim(); |
| return v.isEmpty() ? null : v; |
| } |
| |
| private String getScope() { |
| String scope = comScope.getSelectedItem().toString(); |
| if ("compile".equals(scope)) { //NOI18N |
| //compile is the default scope, no need to explicitly define. |
| scope = null; |
| } |
| return scope; |
| } |
| |
| private String getType() { |
| String t = txtType.getText().trim(); |
| return t.isEmpty() ? null : t; |
| } |
| |
| private String getClassifier() { |
| String c = txtClassifier.getText().trim(); |
| return c.isEmpty() ? null : c; |
| } |
| |
| /** For gaining access to DialogDisplayer instance to manage |
| * warning messages |
| */ |
| private void attachDialogDisplayer(DialogDescriptor dd) { |
| nls = dd.getNotificationLineSupport(); |
| if (nls == null) { |
| nls = dd.createNotificationLineSupport(); |
| } |
| } |
| |
| @Override |
| public void addNotify() { |
| super.addNotify(); |
| assert nls != null : " The notificationLineSupport was not attached to the panel."; //NOI18N |
| } |
| |
| private void setSelectedScope(String type) { |
| comScope.setSelectedItem(type); |
| } |
| |
| @Messages ({"MSG_Defined=Dependency with given groupId and artifactId is already defined in project."}) |
| private void checkValidState() { |
| String gId = txtGroupId.getText().trim(); |
| if (gId.length() <= 0) { |
| gId = null; |
| } |
| String aId = txtArtifactId.getText().trim(); |
| if (aId.length() <= 0) { |
| aId = null; |
| } |
| String version = txtVersion.getText().trim(); |
| if (version.length() <= 0) { |
| version = null; |
| } |
| |
| String warn = null; |
| boolean dmDefined = tabPane.isEnabledAt(2); |
| if (artifactList != null) { |
| Color c = defaultVersionC; |
| if (dmDefined) { |
| if (findConflict(artifactList.getDMDeps(), gId, aId, version, null) == 1) { |
| c = Color.RED; |
| warn = NbBundle.getMessage(AddDependencyPanel.class, "MSG_VersionConflict"); |
| } |
| } |
| txtVersion.setForeground(c); |
| } |
| |
| if (project.getDependencies() != null && gId != null && aId != null) { |
| //poor mans expression evaluator, it's unlikely that some other expressions would be frequent |
| String resolvedGroupId = gId.contains("${project.groupId}") ? gId.replace("${project.groupId}", project.getGroupId()) : gId; |
| String resolvedArtifactId = aId.contains("${project.artifactId}") ? aId.replace("${project.artifactId}", project.getArtifactId()) : aId; |
| |
| for (Dependency dep : project.getDependencies()) { |
| if (resolvedGroupId.equals(dep.getGroupId()) && resolvedArtifactId.equals(dep.getArtifactId())) { |
| warn = Bundle.MSG_Defined(); |
| } |
| |
| } |
| } |
| |
| if (nls != null) { |
| if (warn != null) { |
| nls.setWarningMessage(warn); |
| } else { |
| nls.clearMessages(); |
| } |
| } |
| |
| if (gId == null) { |
| okButton.setEnabled(false); |
| return; |
| } |
| if (aId == null) { |
| okButton.setEnabled(false); |
| return; |
| } |
| if (version == null && !dmDefined) { |
| okButton.setEnabled(false); |
| return; |
| } |
| |
| okButton.setEnabled(true); |
| } |
| |
| private static Border getNbScrollPaneBorder () { |
| Border b = UIManager.getBorder("Nb.ScrollPane.border"); |
| if (b == null) { |
| Color c = UIManager.getColor("controlShadow"); |
| b = new LineBorder(c != null ? c : Color.GRAY); |
| } |
| return b; |
| } |
| |
| /** 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. |
| */ |
| // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents |
| private void initComponents() { |
| |
| lblGroupId = new javax.swing.JLabel(); |
| txtGroupId = new javax.swing.JTextField(); |
| lblArtifactId = new javax.swing.JLabel(); |
| txtArtifactId = new javax.swing.JTextField(); |
| lblVersion = new javax.swing.JLabel(); |
| txtVersion = new javax.swing.JTextField(); |
| lblScope = new javax.swing.JLabel(); |
| comScope = new javax.swing.JComboBox(); |
| lblType = new javax.swing.JLabel(); |
| txtType = new javax.swing.JTextField(); |
| lblClassifier = new javax.swing.JLabel(); |
| txtClassifier = new javax.swing.JTextField(); |
| tabPane = new javax.swing.JTabbedPane(); |
| searchPanel = new javax.swing.JPanel(); |
| searchLabel = new javax.swing.JLabel(); |
| searchField = new javax.swing.JTextField(); |
| jLabel1 = new javax.swing.JLabel(); |
| resultsLabel = new javax.swing.JLabel(); |
| resultsPanel = new javax.swing.JPanel(); |
| jPanel1 = new javax.swing.JPanel(); |
| chkNbOnly = new javax.swing.JCheckBox(); |
| pnlOpen = new javax.swing.JPanel(); |
| jLabel3 = new javax.swing.JLabel(); |
| pnlOpenProjects = new javax.swing.JPanel(); |
| pnlDepMan = new javax.swing.JPanel(); |
| artifactsLabel = new javax.swing.JLabel(); |
| artifactPanel = new javax.swing.JPanel(); |
| jLabel2 = new javax.swing.JLabel(); |
| |
| lblGroupId.setLabelFor(txtGroupId); |
| org.openide.awt.Mnemonics.setLocalizedText(lblGroupId, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "LBL_GroupId")); // NOI18N |
| |
| lblArtifactId.setLabelFor(txtArtifactId); |
| org.openide.awt.Mnemonics.setLocalizedText(lblArtifactId, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "LBL_ArtifactId")); // NOI18N |
| |
| lblVersion.setLabelFor(txtVersion); |
| org.openide.awt.Mnemonics.setLocalizedText(lblVersion, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "LBL_Version")); // NOI18N |
| |
| lblScope.setLabelFor(comScope); |
| org.openide.awt.Mnemonics.setLocalizedText(lblScope, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "LBL_Scope")); // NOI18N |
| |
| comScope.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "compile", "runtime", "test", "provided" })); |
| |
| lblType.setLabelFor(txtType); |
| org.openide.awt.Mnemonics.setLocalizedText(lblType, NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.lblType.text")); // NOI18N |
| |
| lblClassifier.setLabelFor(txtClassifier); |
| org.openide.awt.Mnemonics.setLocalizedText(lblClassifier, NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.lblClassifier.text")); // NOI18N |
| |
| searchPanel.addComponentListener(new java.awt.event.ComponentAdapter() { |
| public void componentShown(java.awt.event.ComponentEvent evt) { |
| searchPanelComponentShown(evt); |
| } |
| }); |
| |
| searchLabel.setLabelFor(searchField); |
| org.openide.awt.Mnemonics.setLocalizedText(searchLabel, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.searchLabel.text", new Object[] {})); // NOI18N |
| |
| searchField.setText(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.searchField.text", new Object[] {})); // NOI18N |
| |
| jLabel1.setForeground(javax.swing.UIManager.getDefaults().getColor("textInactiveText")); |
| org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.jLabel1.text", new Object[] {})); // NOI18N |
| |
| org.openide.awt.Mnemonics.setLocalizedText(resultsLabel, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.resultsLabel.text", new Object[] {})); // NOI18N |
| |
| resultsPanel.setBorder(getNbScrollPaneBorder()); |
| resultsPanel.setLayout(new java.awt.BorderLayout()); |
| |
| javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); |
| jPanel1.setLayout(jPanel1Layout); |
| jPanel1Layout.setHorizontalGroup( |
| jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGap(0, 76, Short.MAX_VALUE) |
| ); |
| jPanel1Layout.setVerticalGroup( |
| jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGap(0, 18, Short.MAX_VALUE) |
| ); |
| |
| org.openide.awt.Mnemonics.setLocalizedText(chkNbOnly, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.chkNbOnly.text")); // NOI18N |
| chkNbOnly.setToolTipText(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.chkNbOnly.toolTipText")); // NOI18N |
| chkNbOnly.addActionListener(new java.awt.event.ActionListener() { |
| public void actionPerformed(java.awt.event.ActionEvent evt) { |
| chkNbOnlyActionPerformed(evt); |
| } |
| }); |
| |
| javax.swing.GroupLayout searchPanelLayout = new javax.swing.GroupLayout(searchPanel); |
| searchPanel.setLayout(searchPanelLayout); |
| searchPanelLayout.setHorizontalGroup( |
| searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, searchPanelLayout.createSequentialGroup() |
| .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) |
| .addGroup(searchPanelLayout.createSequentialGroup() |
| .addGap(12, 12, 12) |
| .addComponent(searchLabel) |
| .addGap(4, 4, 4) |
| .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(jLabel1) |
| .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, searchPanelLayout.createSequentialGroup() |
| .addComponent(searchField, javax.swing.GroupLayout.DEFAULT_SIZE, 365, Short.MAX_VALUE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) |
| .addComponent(chkNbOnly)))) |
| .addGroup(javax.swing.GroupLayout.Alignment.LEADING, searchPanelLayout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(resultsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 554, Short.MAX_VALUE) |
| .addGroup(searchPanelLayout.createSequentialGroup() |
| .addComponent(resultsLabel) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 261, Short.MAX_VALUE) |
| .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addGap(106, 106, 106))))) |
| .addContainerGap()) |
| ); |
| searchPanelLayout.setVerticalGroup( |
| searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(searchPanelLayout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
| .addComponent(searchLabel) |
| .addComponent(searchField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addComponent(chkNbOnly)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(jLabel1) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addComponent(resultsLabel)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(resultsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 198, Short.MAX_VALUE) |
| .addContainerGap()) |
| ); |
| |
| searchField.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.searchField.AccessibleContext.accessibleDescription")); // NOI18N |
| resultsLabel.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.resultsLabel.AccessibleContext.accessibleDescription")); // NOI18N |
| |
| tabPane.addTab(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.searchPanel.TabConstraints.tabTitle", new Object[] {}), null, searchPanel, NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.searchPanel.TabConstraints.tabToolTip")); // NOI18N |
| |
| jLabel3.setLabelFor(pnlOpenProjects); |
| org.openide.awt.Mnemonics.setLocalizedText(jLabel3, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.jLabel3.text")); // NOI18N |
| |
| pnlOpenProjects.setLayout(new java.awt.BorderLayout()); |
| |
| javax.swing.GroupLayout pnlOpenLayout = new javax.swing.GroupLayout(pnlOpen); |
| pnlOpen.setLayout(pnlOpenLayout); |
| pnlOpenLayout.setHorizontalGroup( |
| pnlOpenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(pnlOpenLayout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(pnlOpenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(pnlOpenProjects, javax.swing.GroupLayout.DEFAULT_SIZE, 554, Short.MAX_VALUE) |
| .addComponent(jLabel3)) |
| .addContainerGap()) |
| ); |
| pnlOpenLayout.setVerticalGroup( |
| pnlOpenLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(pnlOpenLayout.createSequentialGroup() |
| .addContainerGap() |
| .addComponent(jLabel3) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(pnlOpenProjects, javax.swing.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE) |
| .addContainerGap()) |
| ); |
| |
| tabPane.addTab(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.pnlOpen.TabConstraints.tabTitle"), null, pnlOpen, NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.pnlOpen.TabConstraints.tabToolTip")); // NOI18N |
| |
| org.openide.awt.Mnemonics.setLocalizedText(artifactsLabel, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.artifactsLabel.text", new Object[] {})); // NOI18N |
| |
| artifactPanel.setBorder(getNbScrollPaneBorder()); |
| artifactPanel.setLayout(new java.awt.BorderLayout()); |
| |
| jLabel2.setForeground(javax.swing.UIManager.getDefaults().getColor("textInactiveText")); |
| org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.jLabel2.text", new Object[] {})); // NOI18N |
| artifactPanel.add(jLabel2, java.awt.BorderLayout.PAGE_END); |
| |
| javax.swing.GroupLayout pnlDepManLayout = new javax.swing.GroupLayout(pnlDepMan); |
| pnlDepMan.setLayout(pnlDepManLayout); |
| pnlDepManLayout.setHorizontalGroup( |
| pnlDepManLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(pnlDepManLayout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(pnlDepManLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(artifactPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 554, Short.MAX_VALUE) |
| .addComponent(artifactsLabel)) |
| .addContainerGap()) |
| ); |
| pnlDepManLayout.setVerticalGroup( |
| pnlDepManLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(pnlDepManLayout.createSequentialGroup() |
| .addContainerGap() |
| .addComponent(artifactsLabel) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(artifactPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 247, Short.MAX_VALUE) |
| .addContainerGap()) |
| ); |
| |
| tabPane.addTab(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.pnlDepMan.TabConstraints.tabTitle", new Object[] {}), null, pnlDepMan, NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.pnlDepMan.TabConstraints.tabToolTip")); // NOI18N |
| |
| javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); |
| this.setLayout(layout); |
| layout.setHorizontalGroup( |
| layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(layout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(lblGroupId) |
| .addComponent(lblArtifactId) |
| .addComponent(lblVersion) |
| .addComponent(lblType)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(txtArtifactId, javax.swing.GroupLayout.DEFAULT_SIZE, 472, Short.MAX_VALUE) |
| .addComponent(txtGroupId, javax.swing.GroupLayout.DEFAULT_SIZE, 472, Short.MAX_VALUE) |
| .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() |
| .addComponent(txtVersion, javax.swing.GroupLayout.DEFAULT_SIZE, 310, Short.MAX_VALUE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(lblScope) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(comScope, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
| .addGroup(layout.createSequentialGroup() |
| .addComponent(txtType, javax.swing.GroupLayout.PREFERRED_SIZE, 169, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(lblClassifier) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(txtClassifier, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE))) |
| .addContainerGap()) |
| .addComponent(tabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 583, Short.MAX_VALUE) |
| ); |
| layout.setVerticalGroup( |
| layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(layout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
| .addComponent(lblGroupId) |
| .addComponent(txtGroupId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
| .addComponent(lblArtifactId) |
| .addComponent(txtArtifactId, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
| .addComponent(lblVersion) |
| .addComponent(txtVersion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addComponent(comScope, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addComponent(lblScope)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) |
| .addComponent(lblType) |
| .addComponent(txtType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addComponent(lblClassifier) |
| .addComponent(txtClassifier, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) |
| .addComponent(tabPane, javax.swing.GroupLayout.DEFAULT_SIZE, 319, Short.MAX_VALUE)) |
| ); |
| |
| txtGroupId.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.txtGroupId.AccessibleContext.accessibleDescription")); // NOI18N |
| txtArtifactId.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.txtArtifactId.AccessibleContext.accessibleDescription")); // NOI18N |
| txtVersion.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.txtVersion.AccessibleContext.accessibleDescription")); // NOI18N |
| comScope.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.comScope.AccessibleContext.accessibleDescription")); // NOI18N |
| tabPane.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(AddDependencyPanel.class, "AddDependencyPanel.tabPane.AccessibleContext.accessibleDescription")); // NOI18N |
| }// </editor-fold>//GEN-END:initComponents |
| |
| private void searchPanelComponentShown(java.awt.event.ComponentEvent evt) {//GEN-FIRST:event_searchPanelComponentShown |
| searchField.requestFocus(); |
| }//GEN-LAST:event_searchPanelComponentShown |
| |
| private void chkNbOnlyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkNbOnlyActionPerformed |
| queryPanel.stateChanged(new ChangeEvent(searchField.getDocument())); |
| }//GEN-LAST:event_chkNbOnlyActionPerformed |
| |
| // Variables declaration - do not modify//GEN-BEGIN:variables |
| private javax.swing.JPanel artifactPanel; |
| private javax.swing.JLabel artifactsLabel; |
| private javax.swing.JCheckBox chkNbOnly; |
| private javax.swing.JComboBox comScope; |
| private javax.swing.JLabel jLabel1; |
| private javax.swing.JLabel jLabel2; |
| private javax.swing.JLabel jLabel3; |
| private javax.swing.JPanel jPanel1; |
| private javax.swing.JLabel lblArtifactId; |
| private javax.swing.JLabel lblClassifier; |
| private javax.swing.JLabel lblGroupId; |
| private javax.swing.JLabel lblScope; |
| private javax.swing.JLabel lblType; |
| private javax.swing.JLabel lblVersion; |
| private javax.swing.JPanel pnlDepMan; |
| private javax.swing.JPanel pnlOpen; |
| private javax.swing.JPanel pnlOpenProjects; |
| private javax.swing.JLabel resultsLabel; |
| private javax.swing.JPanel resultsPanel; |
| private javax.swing.JTextField searchField; |
| private javax.swing.JLabel searchLabel; |
| private javax.swing.JPanel searchPanel; |
| private javax.swing.JTabbedPane tabPane; |
| private javax.swing.JTextField txtArtifactId; |
| private javax.swing.JTextField txtClassifier; |
| private javax.swing.JTextField txtGroupId; |
| private javax.swing.JTextField txtType; |
| private javax.swing.JTextField txtVersion; |
| // End of variables declaration//GEN-END:variables |
| // End of variables declaration |
| |
| private Result<String> populateGroupId() { |
| assert !SwingUtilities.isEventDispatchThread(); |
| final Result<String> result = RepositoryQueries.getGroupsResult(RepositoryPreferences.getInstance().getRepositoryInfos()); |
| final List<String> lst = new ArrayList<String>(result.getResults()); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| groupCompleter.setValueList(lst, result.isPartial()); |
| } |
| }); |
| return result; |
| } |
| |
| private Result<String> populateArtifact(String groupId) { |
| assert !SwingUtilities.isEventDispatchThread(); |
| final Result<String> result = RepositoryQueries.getArtifactsResult(groupId, RepositoryPreferences.getInstance().getRepositoryInfos()); |
| final List<String> lst = new ArrayList<String>(result.getResults()); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| artifactCompleter.setValueList(lst, result.isPartial()); |
| } |
| }); |
| return result; |
| } |
| |
| private Result<NBVersionInfo> populateVersion(String groupId, String artifactId) { |
| assert !SwingUtilities.isEventDispatchThread(); |
| final Result<NBVersionInfo> result = RepositoryQueries.getVersionsResult(groupId, artifactId, RepositoryPreferences.getInstance().getRepositoryInfos()); |
| List<NBVersionInfo> lst = result.getResults(); |
| final List<String> vers = new ArrayList<String>(); |
| for (NBVersionInfo rec : lst) { |
| if (!vers.contains(rec.getVersion())) { |
| vers.add(rec.getVersion()); |
| } |
| } |
| // also include properties/expressions that could be related to version |
| // management |
| List<String> propList = new ArrayList<String>(); |
| for (Object propKey : project.getProperties().keySet()) { |
| String key = (String)propKey; |
| if (key.endsWith(".version")) { //NOI18N |
| // is this the correct heuristics? |
| propList.add("${" + key + "}"); |
| } |
| } |
| Collections.sort(propList); |
| vers.addAll(propList); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| versionCompleter.setValueList(vers, result.isPartial()); |
| } |
| }); |
| return result; |
| } |
| |
| private static List<Dependency> getDependenciesFromDM(MavenProject project, Project nbprj) { |
| NbMavenProjectImpl p = nbprj.getLookup().lookup(NbMavenProjectImpl.class); |
| MavenProject localProj = project; |
| DependencyManagement curDM; |
| List<Dependency> result = new ArrayList<Dependency>(); |
| //mkleint: without the managementKey checks I got some entries multiple times. |
| // do we actually need to traverse the parent poms, are they completely resolved anyway? |
| //XXX |
| Set<String> knownKeys = new HashSet<String>(); |
| |
| while (localProj != null) { |
| curDM = localProj.getDependencyManagement(); |
| if (curDM != null) { |
| @SuppressWarnings("unchecked") |
| List<Dependency> ds = curDM.getDependencies(); |
| for (Dependency d : ds) { |
| if (knownKeys.contains(d.getManagementKey())) { |
| continue; |
| } |
| result.add(d); |
| knownKeys.add(d.getManagementKey()); |
| } |
| } |
| try { |
| localProj = p.loadParentOf(EmbedderFactory.getProjectEmbedder(), localProj); |
| } catch (ProjectBuildingException x) { |
| break; |
| } |
| } |
| Collections.sort(result, new Comparator<Dependency>() { |
| |
| @Override |
| public int compare(Dependency o1, Dependency o2) { |
| return o1.getManagementKey().compareTo(o2.getManagementKey()); |
| } |
| }); |
| return result; |
| } |
| |
| /** |
| * @return 0 -> no conflicts, 1 -> conflict in version, 2 -> conflict in scope |
| */ |
| private static int findConflict (List<Dependency> deps, String groupId, String artifactId, String version, String scope) { |
| if (deps == null) { |
| return 0; |
| } |
| for (Dependency dep : deps) { |
| if (artifactId != null && artifactId.equals(dep.getArtifactId()) && |
| groupId != null && groupId.equals(dep.getGroupId())) { |
| if (version != null && !version.equals(dep.getVersion())) { |
| return 1; |
| } |
| if (scope != null) { |
| if (!scope.equals(dep.getScope())) { |
| return 2; |
| } |
| } else if (dep.getScope() != null) { |
| return 2; |
| } |
| |
| } |
| } |
| |
| return 0; |
| } |
| |
| private void setFields(String groupId, String artifactId, String version, String type, String classifier) { |
| boolean sameGrId = false; |
| if (groupId != null && groupId.equals(project.getGroupId())) { |
| groupId = "${project.groupId}"; //NOI18N |
| sameGrId = true; |
| } |
| txtGroupId.setText(groupId); |
| txtArtifactId.setText(artifactId); |
| if (sameGrId && version != null && version.equals(project.getVersion())) { |
| version = "${project.version}"; //NOI18N |
| } |
| txtVersion.setText(version); |
| if (type != null) { |
| if (type.equals("jar") || |
| (("nbm".equals(project.getPackaging()) || "nbm-application".equals(project.getPackaging())) && type.equals("nbm"))) {//NOI18N |
| type = null; |
| } |
| } |
| txtType.setText(type); |
| txtClassifier.setText(classifier); |
| } |
| |
| private static Node noResultsNode, searchingNode, tooGeneralNode; |
| |
| private static Node getNoResultsNode() { |
| if (noResultsNode == null) { |
| AbstractNode nd = new AbstractNode(Children.LEAF) { |
| |
| @Override |
| public Image getIcon(int arg0) { |
| return ImageUtilities.loadImage(EMPTY_ICON); //NOI18N |
| } |
| |
| @Override |
| public Image getOpenedIcon(int arg0) { |
| return getIcon(arg0); |
| } |
| }; |
| nd.setName("Empty"); //NOI18N |
| |
| nd.setDisplayName(NbBundle.getMessage(AddDependencyPanel.class, "LBL_Node_Empty")); //NOI18N |
| |
| noResultsNode = nd; |
| } |
| |
| return new FilterNode (noResultsNode, Children.LEAF); |
| } |
| |
| private static Node getSearchingNode() { |
| if (searchingNode == null) { |
| AbstractNode nd = new AbstractNode(Children.LEAF) { |
| |
| @Override |
| public Image getIcon(int arg0) { |
| return ImageUtilities.loadImage(WAIT_ICON); //NOI18N |
| } |
| |
| @Override |
| public Image getOpenedIcon(int arg0) { |
| return getIcon(arg0); |
| } |
| }; |
| nd.setName("Searching"); //NOI18N |
| |
| nd.setDisplayName(NbBundle.getMessage(AddDependencyPanel.class, "LBL_Node_Searching")); //NOI18N |
| |
| searchingNode = nd; |
| } |
| |
| return new FilterNode (searchingNode, Children.LEAF); |
| } |
| |
| private static Node getTooGeneralNode() { |
| if (tooGeneralNode == null) { |
| AbstractNode nd = new AbstractNode(Children.LEAF) { |
| |
| @Override |
| public Image getIcon(int arg0) { |
| return ImageUtilities.loadImage(EMPTY_ICON); //NOI18N |
| } |
| |
| @Override |
| public Image getOpenedIcon(int arg0) { |
| return getIcon(arg0); |
| } |
| }; |
| nd.setName("Too General"); //NOI18N |
| |
| nd.setDisplayName(NbBundle.getMessage(AddDependencyPanel.class, "LBL_Node_TooGeneral")); //NOI18N |
| |
| tooGeneralNode = nd; |
| } |
| |
| return new FilterNode (tooGeneralNode, Children.LEAF); |
| } |
| |
| private class ResultsRootNode extends AbstractNode { |
| |
| private ResultsRootChildren resultsChildren; |
| |
| public ResultsRootNode() { |
| this(new InstanceContent()); |
| } |
| |
| private ResultsRootNode(InstanceContent content) { |
| super (new ResultsRootChildren(), new AbstractLookup(content)); |
| content.add(this); |
| this.resultsChildren = (ResultsRootChildren) getChildren(); |
| } |
| |
| public void setOneChild(Node n) { |
| List<Node> ch = new ArrayList<Node>(1); |
| ch.add(n); |
| setNewChildren(ch); |
| } |
| |
| public void setNewChildren(List<Node> ch) { |
| resultsChildren.setNewChildren (ch); |
| } |
| } |
| |
| private class ResultsRootChildren extends Children.Keys<Node> { |
| |
| List<Node> myNodes; |
| |
| public ResultsRootChildren() { |
| myNodes = Collections.EMPTY_LIST; |
| } |
| |
| private void setNewChildren(List<Node> ch) { |
| myNodes = ch; |
| refreshList(); |
| } |
| |
| @Override |
| protected void addNotify() { |
| refreshList(); |
| } |
| |
| private void refreshList() { |
| List<Node> keys = new ArrayList(); |
| for (Node node : myNodes) { |
| keys.add(node); |
| } |
| setKeys(keys); |
| } |
| |
| @Override |
| protected Node[] createNodes(Node key) { |
| return new Node[] { key }; |
| } |
| |
| } |
| |
| private static final Object LOCK = new Object(); |
| |
| private class QueryPanel extends JPanel implements ExplorerManager.Provider, |
| Comparator<String>, PropertyChangeListener, ChangeListener { |
| |
| |
| private final BeanTreeView btv; |
| private final ExplorerManager manager; |
| private final ResultsRootNode resultsRootNode; |
| |
| private String inProgressText, lastQueryText, curTypedText; |
| |
| private final Color defSearchC; |
| |
| private QueryPanel() { |
| btv = new BeanTreeView(); |
| btv.setRootVisible(false); |
| btv.setDefaultActionAllowed(true); |
| btv.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); |
| manager = new ExplorerManager(); |
| setLayout(new BorderLayout()); |
| add(btv, BorderLayout.CENTER); |
| defSearchC = AddDependencyPanel.this.searchField.getForeground(); |
| manager.addPropertyChangeListener(this); |
| AddDependencyPanel.this.resultsLabel.setLabelFor(btv); |
| btv.getAccessibleContext().setAccessibleDescription(AddDependencyPanel.this.resultsLabel.getAccessibleContext().getAccessibleDescription()); |
| resultsRootNode = new ResultsRootNode(); |
| manager.setRootContext(resultsRootNode); |
| } |
| |
| /** delayed change of query text */ |
| @Override |
| public void stateChanged (ChangeEvent e) { |
| Document doc = (Document)e.getSource(); |
| try { |
| curTypedText = doc.getText(0, doc.getLength()).trim(); |
| } catch (BadLocationException ex) { |
| // should never happen, nothing we can do probably |
| return; |
| } |
| |
| AddDependencyPanel.this.searchField.setForeground(defSearchC); |
| |
| if (curTypedText.length() > 0) { |
| find(curTypedText); |
| } |
| } |
| |
| private boolean cancel() { |
| synchronized (LOCK) { |
| if (lastQueryText != null && !lastQueryText.equals(inProgressText)) { |
| return true; //we no longer care |
| } |
| } |
| return false; |
| } |
| |
| |
| @Messages({"MSG_ClassesExcluded=Too general query. Class names excluded from the search.", |
| "# {0} - number", |
| "# {1} - total number", |
| "MSG_Narrow=Only {0} of {1} results shown. Consider narrowing your search." |
| }) |
| void find(String queryText) { |
| synchronized (LOCK) { |
| if (inProgressText != null) { |
| lastQueryText = queryText; |
| // stop waiting for results of the previous search |
| //TODO we want to have the current task cancelled and new one started. |
| //currently we wait for the first one to finish, which takes forever in some cases. |
| |
| return; |
| } |
| inProgressText = queryText; |
| lastQueryText = null; |
| } |
| |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| resultsRootNode.setOneChild(getSearchingNode()); |
| AddDependencyPanel.this.searchField.setForeground(defSearchC); |
| AddDependencyPanel.this.nls.clearMessages(); |
| } |
| }); |
| |
| final List<QueryField> fields = new ArrayList<QueryField>(); |
| final List<QueryField> fieldsNonClasses = new ArrayList<QueryField>(); |
| String q = queryText.trim(); |
| String[] splits = q.split(" "); //NOI118N |
| |
| List<String> fStrings = new ArrayList<String>(); |
| fStrings.add(QueryField.FIELD_GROUPID); |
| fStrings.add(QueryField.FIELD_ARTIFACTID); |
| fStrings.add(QueryField.FIELD_VERSION); |
| fStrings.add(QueryField.FIELD_NAME); |
| fStrings.add(QueryField.FIELD_DESCRIPTION); |
| fStrings.add(QueryField.FIELD_CLASSES); |
| |
| for (String curText : splits) { |
| for (String fld : fStrings) { |
| QueryField f = new QueryField(); |
| f.setField(fld); |
| f.setValue(curText); |
| fields.add(f); |
| if (!QueryField.FIELD_CLASSES.equals(fld)) { |
| fieldsNonClasses.add(f); |
| } |
| } |
| } |
| |
| |
| Task t = RPofQueryPanel.post(new Runnable() { |
| |
| @Override |
| public void run() { |
| if (cancel()) return;//we no longer care |
| //first try with classes search included, |
| try { |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| AddDependencyPanel.this.nls.setInformationMessage(null); //NOI18N |
| } |
| }); |
| final Result<NBVersionInfo> result = RepositoryQueries.findResult(fields, RepositoryPreferences.getInstance().getRepositoryInfos()); |
| if (cancel()) return;//we no longer care |
| updateResults(result.getResults(), result.isPartial()); |
| if (result.isPartial()) { |
| if (cancel()) return;//we no longer care |
| result.waitForSkipped(); |
| if (cancel()) return;//we no longer care |
| updateResults(result.getResults(), false); |
| } |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| if (result.getReturnedResultCount() < result.getTotalResultCount()) { |
| AddDependencyPanel.this.nls.setInformationMessage(MSG_Narrow(result.getReturnedResultCount(), result.getTotalResultCount())); |
| } |
| } |
| }); |
| |
| } catch (BooleanQuery.TooManyClauses exc) { |
| if (cancel()) return;//we no longer care |
| // if failing, then exclude classes from search.. |
| try { |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| AddDependencyPanel.this.nls.setInformationMessage(MSG_ClassesExcluded()); |
| } |
| }); |
| Result<NBVersionInfo> result = RepositoryQueries.findResult(fieldsNonClasses, RepositoryPreferences.getInstance().getRepositoryInfos()); |
| if (cancel()) return;//we no longer care |
| updateResults(result.getResults(), result.isPartial()); |
| if (result.isPartial()) { |
| result.waitForSkipped(); |
| if (cancel()) return;//we no longer care |
| updateResults(result.getResults(), false); |
| } |
| } catch (BooleanQuery.TooManyClauses exc2) { |
| // if still failing, report to the user |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| AddDependencyPanel.this.searchField.setForeground(Color.RED); |
| AddDependencyPanel.this.nls.setWarningMessage(NbBundle.getMessage(AddDependencyPanel.class, "MSG_TooGeneral")); //NOI18N |
| resultsRootNode.setOneChild(getTooGeneralNode()); |
| } |
| }); |
| } |
| } catch (OutOfMemoryError oome) { |
| // running into OOME may still happen in Lucene despite the fact that |
| // we are trying hard to prevent it in NexusRepositoryIndexerImpl |
| // (see #190265) |
| // in the bad circumstances theoretically any thread may encounter OOME |
| // but most probably this thread will be it |
| // trying to indicate the condition to the user here |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| AddDependencyPanel.this.searchField.setForeground(Color.RED); |
| AddDependencyPanel.this.nls.setWarningMessage(NbBundle.getMessage(AddDependencyPanel.class, "MSG_TooGeneral")); //NOI18N |
| resultsRootNode.setOneChild(getTooGeneralNode()); |
| } |
| }); |
| } |
| } |
| }); |
| |
| t.addTaskListener(new TaskListener() { |
| |
| @Override |
| public void taskFinished(Task task) { |
| synchronized (LOCK) { |
| String localText = inProgressText; |
| inProgressText = null; |
| if (lastQueryText != null && !lastQueryText.equals(localText)) { |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| if (lastQueryText != null) { |
| find(lastQueryText); |
| } |
| } |
| }); |
| } |
| } |
| } |
| }); |
| } |
| |
| @Override |
| public ExplorerManager getExplorerManager() { |
| return manager; |
| } |
| |
| void updateResults(List<NBVersionInfo> infos, final boolean partial) { |
| final Map<String, List<NBVersionInfo>> map = new HashMap<String, List<NBVersionInfo>>(); |
| |
| if (infos != null) { |
| if (chkNbOnly.isSelected()) { // #181656: show only NB modules |
| List<NBVersionInfo> refined = new ArrayList<NBVersionInfo>(); |
| Map<String, NBVersionInfo> check = new HashMap<String, NBVersionInfo>(); // class index works only on JAR artifacts |
| Set<String> found = new HashSet<String>(); // but search string might also be found in other fields |
| for (NBVersionInfo nbvi : infos) { |
| String key = key(nbvi); |
| if (NbMavenProject.TYPE_NBM.equals(nbvi.getPackaging())) { |
| refined.add(nbvi); |
| found.add(key); |
| } else { |
| check.put(key, nbvi); |
| } |
| } |
| final Result<String> findResult = RepositoryQueries.getGAVsForPackaging(NbMavenProject.TYPE_NBM, RepositoryPreferences.getInstance().getRepositoryInfos()); |
| for (String alt : findResult.getResults()) { |
| if (check.containsKey(alt) && !found.contains(alt)) { |
| refined.add(check.get(alt)); |
| } |
| } |
| Collections.sort(refined); |
| infos = refined; |
| } |
| for (NBVersionInfo nbvi : infos) { |
| String key = nbvi.getGroupId() + " : " + nbvi.getArtifactId(); //NOI18n |
| List<NBVersionInfo> get = map.get(key); |
| if (get == null) { |
| get = new ArrayList<NBVersionInfo>(); |
| map.put(key, get); |
| } |
| get.add(nbvi); |
| } |
| } |
| |
| final List<String> keyList = new ArrayList<String>(map.keySet()); |
| // sort specially using our comparator, see compare method |
| Collections.sort(keyList, QueryPanel.this); |
| |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| updateResultNodes(keyList, map, partial); |
| } |
| }); |
| } |
| |
| |
| private void updateResultNodes(List<String> keyList, Map<String, List<NBVersionInfo>> map, boolean partial) { |
| |
| if (keyList.size() > 0) { // some results available |
| |
| Map<String, Node> currentNodes = new HashMap<String, Node>(); |
| for (Node nd : resultsRootNode.getChildren().getNodes()) { |
| currentNodes.put(nd.getName(), nd); |
| } |
| List<Node> newNodes = new ArrayList<Node>(keyList.size()); |
| |
| // still searching? |
| if (partial) |
| newNodes.add(getSearchingNode()); |
| |
| for (String key : keyList) { |
| Node nd; |
| nd = currentNodes.get(key); |
| if (null != nd) { |
| ((MavenNodeFactory.ArtifactNode)((FilterNodeWithDefAction)nd).getOriginal()).setVersionInfos(map.get(key)); |
| } else { |
| nd = createFilterWithDefaultAction(MavenNodeFactory.createArtifactNode(key, map.get(key)), false); |
| } |
| newNodes.add(nd); |
| } |
| |
| resultsRootNode.setNewChildren(newNodes); |
| } else if (partial) { // still searching, no results yet |
| resultsRootNode.setOneChild(getSearchingNode()); |
| } else { // finished searching with no results |
| resultsRootNode.setOneChild(getNoResultsNode()); |
| } |
| } |
| |
| /** Impl of comparator, sorts artifacts asfabetically with exception |
| * of items that contain current query string, which take precedence. |
| */ |
| @Override |
| public int compare(String s1, String s2) { |
| |
| int index1 = s1.indexOf(inProgressText); |
| int index2 = s2.indexOf(inProgressText); |
| |
| if (index1 >= 0 || index2 >=0) { |
| if (index1 < 0) { |
| return 1; |
| } else if (index2 < 0) { |
| return -1; |
| } |
| return s1.compareTo(s2); |
| } else { |
| return s1.compareTo(s2); |
| } |
| } |
| |
| /** PropertyChangeListener impl, stores maven coordinates of selected artifact */ |
| @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| if (ExplorerManager.PROP_SELECTED_NODES.equals(evt.getPropertyName())) { |
| Node[] selNodes = manager.getSelectedNodes(); |
| changeSelection(selNodes.length == 1 ? selNodes[0].getLookup() : Lookup.EMPTY); |
| } |
| } |
| |
| private String key(NBVersionInfo nbvi) { |
| return nbvi.getGroupId() + ':' + nbvi.getArtifactId() + ':' + nbvi.getVersion(); |
| } |
| |
| } // QueryPanel |
| |
| private static final Object DM_DEPS_LOCK = new Object(); |
| private class DMListPanel extends JPanel implements ExplorerManager.Provider, |
| AncestorListener, ActionListener, PropertyChangeListener, Runnable { |
| |
| private final BeanTreeView btv; |
| private final ExplorerManager manager; |
| private final MavenProject project; |
| private Node noDMRoot; |
| |
| private List<Dependency> dmDeps; |
| |
| public DMListPanel(MavenProject project) { |
| this.project = project; |
| btv = new BeanTreeView(); |
| btv.setRootVisible(false); |
| btv.setDefaultActionAllowed(true); |
| //lv.setDefaultProcessor(this); |
| manager = new ExplorerManager(); |
| manager.addPropertyChangeListener(this); |
| setLayout(new BorderLayout()); |
| add(btv, BorderLayout.CENTER); |
| addAncestorListener(this); |
| AddDependencyPanel.this.artifactsLabel.setLabelFor(btv); |
| |
| // disable tab if DM section not defined |
| RPofDMListPanel.post(this); |
| } |
| |
| @Override |
| public ExplorerManager getExplorerManager() { |
| return manager; |
| } |
| |
| private NBVersionInfo convert2VInfo(Dependency dep) { |
| return new NBVersionInfo(null, dep.getGroupId(), dep.getArtifactId(), |
| dep.getVersion(), dep.getType(), null, null, null, dep.getClassifier()); |
| } |
| |
| private List<Dependency> getDMDeps() { |
| synchronized (DM_DEPS_LOCK) { |
| return dmDeps; |
| } |
| } |
| |
| private void loadArtifacts() { |
| List<Dependency> deps = getDMDeps(); |
| if (deps == null || deps.isEmpty()) { |
| if (noDMRoot == null) { |
| AbstractNode nd = new AbstractNode(Children.LEAF) { |
| @Override |
| public Image getIcon(int arg0) { |
| return ImageUtilities.loadImage(EMPTY_ICON); //NOI18N |
| } |
| @Override |
| public Image getOpenedIcon(int arg0) { |
| return getIcon(arg0); |
| } |
| }; |
| nd.setName("Empty"); //NOI18N |
| nd.setDisplayName(NbBundle.getMessage(AddDependencyPanel.class, "LBL_DM_Empty")); |
| Children.Array array = new Children.Array(); |
| array.add(new Node[]{nd}); |
| noDMRoot = new AbstractNode(array); |
| } |
| manager.setRootContext(noDMRoot); |
| } else { |
| Children.Array array = new Children.Array(); |
| Node root = new AbstractNode(array); |
| for (Dependency dep : deps) { |
| array.add(new Node[]{ createFilterWithDefaultAction(MavenNodeFactory.createVersionNode(convert2VInfo(dep), true), true) }); |
| } |
| manager.setRootContext(root); |
| } |
| } |
| |
| @Override |
| public void ancestorAdded(AncestorEvent event) { |
| loadArtifacts(); |
| } |
| |
| @Override |
| public void ancestorRemoved(AncestorEvent event) { |
| } |
| |
| @Override |
| public void ancestorMoved(AncestorEvent event) { |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| Node[] selNodes = manager.getSelectedNodes(); |
| changeSelection(selNodes.length == 1 ? selNodes[0].getLookup() : Lookup.EMPTY); |
| } |
| |
| /** Loads dependencies outside EQ thread, updates tab state in EQ */ |
| @Override |
| public void run() { |
| synchronized (DM_DEPS_LOCK) { |
| dmDeps = getDependenciesFromDM(project, AddDependencyPanel.this.nbProject); |
| } |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| boolean dmEmpty = dmDeps.isEmpty(); |
| tabPane.setEnabledAt(2, !dmEmpty); |
| } |
| }); |
| } |
| |
| } |
| |
| |
| private class OpenListPanel extends JPanel implements ExplorerManager.Provider, |
| PropertyChangeListener, Runnable { |
| |
| private final BeanTreeView btv; |
| private final ExplorerManager manager; |
| private final Project project; |
| |
| public OpenListPanel(Project project) { |
| this.project = project; |
| btv = new BeanTreeView(); |
| btv.setRootVisible(false); |
| btv.setDefaultActionAllowed(true); |
| manager = new ExplorerManager(); |
| manager.addPropertyChangeListener(this); |
| setLayout(new BorderLayout()); |
| add(btv, BorderLayout.CENTER); |
| |
| RPofOpenListPanel.post(this); |
| } |
| |
| @Override |
| public ExplorerManager getExplorerManager() { |
| return manager; |
| } |
| |
| @Override |
| public void propertyChange(PropertyChangeEvent evt) { |
| Node[] selNodes = manager.getSelectedNodes(); |
| changeSelection(selNodes.length == 1 ? selNodes[0].getLookup() : Lookup.EMPTY); |
| } |
| |
| /** Loads dependencies outside EQ thread, updates tab state in EQ */ |
| @Override |
| public void run() { |
| Project[] prjs = OpenProjects.getDefault().getOpenProjects(); |
| final List<Node> toRet = new ArrayList<Node>(); |
| for (Project p : prjs) { |
| if (p == project) { |
| continue; |
| } |
| NbMavenProject mav = p.getLookup().lookup(NbMavenProject.class); |
| if (mav != null) { |
| boolean continueProjectIteration = false; |
| MavenProject mavenProject = mav.getMavenProject(); |
| Iterator<Dependency> iterator = project.getLookup().lookup(NbMavenProject.class).getMavenProject().getDependencies().iterator(); |
| while (iterator.hasNext()) { |
| Dependency dependency = iterator.next(); |
| if (mavenProject.getGroupId().equals(dependency.getGroupId()) |
| && mavenProject.getArtifactId().equals(dependency.getArtifactId())) { |
| continueProjectIteration = true; |
| break; |
| } |
| } |
| if ( continueProjectIteration ) { |
| continue; |
| } |
| LogicalViewProvider lvp = p.getLookup().lookup(LogicalViewProvider.class); |
| toRet.add(createFilterWithDefaultAction(lvp.createLogicalView(), true)); |
| } |
| } |
| Children.Array ch = new Children.Array(); |
| ch.add(toRet.toArray(new Node[0])); |
| Node root = new AbstractNode(ch); |
| getExplorerManager().setRootContext(root); |
| SwingUtilities.invokeLater(new Runnable() { |
| @Override |
| public void run() { |
| boolean opEmpty = toRet.isEmpty(); |
| tabPane.setEnabledAt(1, !opEmpty); |
| } |
| }); |
| } |
| |
| } |
| |
| private class DefAction extends AbstractAction implements ContextAwareAction { |
| private final boolean close; |
| private final Lookup lookup; |
| |
| public DefAction(boolean closeNow, Lookup look) { |
| this.close = closeNow; |
| lookup = look; |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| Project prj = lookup.lookup(Project.class); |
| boolean set = false; |
| if (prj != null) { |
| NbMavenProject mav = prj.getLookup().lookup(NbMavenProject.class); |
| MavenProject m = mav.getMavenProject(); |
| AddDependencyPanel.this.setFields(m.getGroupId(), m.getArtifactId(), m.getVersion(), null, null); |
| set = true; |
| } |
| if (!set) { |
| NBVersionInfo vi = lookup.lookup(NBVersionInfo.class); |
| if (vi != null) { |
| //in dm panel we want to pass empty version |
| boolean isDM = lookup.lookup(DependencyManagement.class) != null; |
| String ver = isDM ? "" : vi.getVersion(); |
| String type = isDM ? "" : vi.getType(); |
| String classifier = isDM ? "" : vi.getClassifier(); |
| AddDependencyPanel.this.setFields(vi.getGroupId(), vi.getArtifactId(), ver, type, classifier); |
| set = true; |
| } |
| } |
| if (set) { |
| if (close) { |
| AddDependencyPanel.this.getOkButton().doClick(); |
| } else { |
| //reset completion. |
| AddDependencyPanel.this.artifactCompleter.setLoading(true); |
| AddDependencyPanel.this.versionCompleter.setLoading(true); |
| final String groupId = txtGroupId.getText().trim(); |
| final String artifactId = txtArtifactId.getText().trim(); |
| RP.post(new Runnable() { |
| @Override public void run() { |
| populateArtifact(groupId); |
| populateVersion(groupId, artifactId); |
| } |
| }); |
| } |
| } else { |
| AddDependencyPanel.this.setFields("", "", "", "", ""); //NOI18N |
| //reset completion. |
| AddDependencyPanel.this.artifactCompleter.setValueList(Collections.<String>emptyList(), false); |
| AddDependencyPanel.this.versionCompleter.setValueList(Collections.<String>emptyList(), false); |
| } |
| } |
| |
| @Override |
| public Action createContextAwareInstance(Lookup actionContext) { |
| return new DefAction(close, actionContext); |
| } |
| |
| } |
| |
| private void changeSelection(Lookup context) { |
| new DefAction(false, context).actionPerformed(null); |
| } |
| |
| private Node createFilterWithDefaultAction(final Node nd, boolean leaf) { |
| return new FilterNodeWithDefAction (nd, leaf); |
| } |
| |
| class FilterNodeWithDefAction extends FilterNode { |
| |
| public FilterNodeWithDefAction(Node nd, boolean leaf) { |
| super(nd, leaf ? Children.LEAF : new FilterNode.Children(nd) { |
| @Override |
| protected Node[] createNodes(Node key) { |
| return new Node[]{createFilterWithDefaultAction(key, true)}; |
| } |
| }); |
| } |
| |
| @Override |
| public Action getPreferredAction() { |
| return super.getPreferredAction(); |
| } |
| |
| @Override |
| public Action[] getActions(boolean context) { |
| return new Action[0]; |
| } |
| |
| @Override |
| public Node getOriginal() { |
| return super.getOriginal(); |
| } |
| } |
| } |