| /* |
| * 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.autoupdate.pluginimporter; |
| |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.io.File; |
| import java.io.IOException; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.prefs.BackingStoreException; |
| import java.util.prefs.Preferences; |
| import javax.swing.AbstractAction; |
| import javax.swing.JButton; |
| import javax.swing.JComponent; |
| import javax.swing.JLabel; |
| import javax.swing.SwingConstants; |
| import javax.swing.SwingUtilities; |
| import javax.swing.table.AbstractTableModel; |
| import javax.swing.table.TableColumn; |
| import javax.swing.table.TableModel; |
| import org.netbeans.api.autoupdate.InstallSupport; |
| import org.netbeans.api.autoupdate.OperationContainer; |
| import org.netbeans.api.autoupdate.UpdateElement; |
| import org.netbeans.api.progress.ProgressHandle; |
| import org.netbeans.api.progress.ProgressHandleFactory; |
| import org.netbeans.modules.autoupdate.ui.api.PluginManager; |
| import org.openide.DialogDescriptor; |
| import org.openide.DialogDisplayer; |
| import org.openide.NotifyDescriptor; |
| import org.openide.awt.Mnemonics; |
| import org.openide.awt.Notification; |
| import org.openide.awt.NotificationDisplayer; |
| import org.openide.util.Exceptions; |
| import org.openide.util.ImageUtilities; |
| import org.openide.util.NbBundle; |
| import org.openide.util.NbPreferences; |
| import org.openide.util.RequestProcessor; |
| |
| /** |
| * |
| * @author Jirka Rechtacek |
| */ |
| public class ImportManager extends java.awt.Panel { |
| private final File srcCluster; |
| private final File dest; |
| private final PluginImporter importer; |
| private static ImportManager INSTANCE = null; |
| private List<Boolean> checkedToInstall = Collections.emptyList (); |
| private List<Boolean> checkedToImport = Collections.emptyList (); |
| private List<UpdateElement> toInstall = Collections.emptyList (); |
| private List<UpdateElement> toImport = Collections.emptyList (); |
| private Notification currentNotification = null; |
| private JButton bImport; |
| private JButton bNo; |
| |
| /** Creates new form ImportManager */ |
| @SuppressWarnings("LeakingThisInConstructor") |
| public ImportManager (File src, File dest, PluginImporter importer) { |
| this.srcCluster = src; |
| this.dest = dest; |
| this.importer = importer; |
| initialize(); |
| INSTANCE = this; |
| } |
| |
| public PluginImporter getPluginImporter() { |
| return importer; |
| } |
| |
| private void initialize() { |
| toInstall = new ArrayList<UpdateElement> (importer.getPluginsAvailableToInstall ()); |
| Collections.sort (toInstall, new Comparator<UpdateElement> () { |
| @Override |
| public int compare (UpdateElement o1, UpdateElement o2) { |
| return o1.getDisplayName ().compareTo (o2.getDisplayName ()); |
| } |
| }); |
| checkedToInstall = new ArrayList<Boolean> (Collections.nCopies (importer.getPluginsAvailableToInstall ().size (), Boolean.TRUE)); |
| |
| toImport = new ArrayList<UpdateElement> (importer.getPluginsToImport ()); |
| Collections.sort (toImport, new Comparator<UpdateElement> () { |
| @Override |
| public int compare (UpdateElement o1, UpdateElement o2) { |
| return o1.getDisplayName ().compareTo (o2.getDisplayName ()); |
| } |
| }); |
| checkedToImport = new ArrayList<Boolean> (Collections.nCopies (toImport.size (), Boolean.FALSE)); |
| |
| initComponents(); |
| |
| tpBroken.setEnabled (!importer.getBrokenPlugins ().isEmpty ()); |
| lBroken.setEnabled (!importer.getBrokenPlugins ().isEmpty ()); |
| if (! importer.getBrokenPlugins ().isEmpty ()) { |
| tpBroken.setText (importer.getBrokenPlugins ().toString ()); |
| } |
| refreshUI (); |
| } |
| |
| public static ImportManager getInstance () { |
| return INSTANCE; |
| } |
| |
| public void notifyAvailable () { |
| remindLater (); |
| String msg = NbBundle.getMessage (ImportManager.class, |
| "ImportNotifier_PluginAvailableForImport", // NOI18N |
| toImport.size () + toInstall.size ()); |
| String details = NbBundle.getMessage (ImportManager.class, |
| "ImportNotifier_PluginAvailableForImport_Details", // NOI18N |
| srcCluster); |
| MyAction a = new MyAction(); |
| synchronized( this ) { |
| if( null != currentNotification ) { |
| currentNotification.clear(); |
| } |
| Notification notification = NotificationDisplayer.getDefault().notify(msg, |
| ImageUtilities.loadImageIcon("org/netbeans/modules/autoupdate/pluginimporter/resources/import.png", false), //NOI18N |
| details, |
| a); |
| a.notification = notification; |
| currentNotification = notification; |
| } |
| } |
| |
| private class MyAction extends AbstractAction { |
| final JButton bRemindLaterButton = new JButton (); |
| final JButton bImportButton = new JButton (); |
| final JButton bNoButton = new JButton (); |
| private Notification notification; |
| |
| public MyAction() { |
| Mnemonics.setLocalizedText (bRemindLaterButton, NbBundle.getMessage (ImportManager.class, "ImportNotifier_bRemindLater")); |
| Mnemonics.setLocalizedText (bImportButton, NbBundle.getMessage (ImportManager.class, "ImportNotifier_bImport")); |
| Mnemonics.setLocalizedText (bNoButton, NbBundle.getMessage (ImportManager.class, "ImportNotifier_bNo")); |
| } |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| ImportManager ui = ImportManager.getInstance (); |
| ui.getPluginImporter().reinspect(); |
| ui.initialize(); |
| |
| ui.attachButtons (bImportButton, bNoButton); |
| DialogDescriptor dd = new DialogDescriptor ( |
| ui, |
| NbBundle.getMessage (Installer.class, "Installer_DialogTitle"), |
| true, |
| new Object[] {bImportButton, bNoButton, bRemindLaterButton}, |
| NotifyDescriptor.OK_OPTION, |
| DialogDescriptor.BOTTOM_ALIGN, |
| null, |
| null); |
| dd.setClosingOptions (new Object[] {bImportButton, bNoButton, bRemindLaterButton}); |
| DialogDisplayer.getDefault ().createDialog (dd).setVisible (true); |
| if (bImportButton.equals (dd.getValue ()) || bNoButton.equals (dd.getValue ())) { |
| ui.dontRemind (); |
| SwingUtilities.invokeLater (new Runnable () { |
| @Override |
| public void run () { |
| if( null != notification ) { |
| notification.clear(); |
| } |
| } |
| }); |
| } else if (bRemindLaterButton.equals (dd.getValue ())) { |
| ui.remindLater (); |
| } |
| } |
| } |
| |
| public void attachButtons(JButton bImport, JButton bNo) { |
| this.bImport = bImport; |
| this.bNo = bNo; |
| bImport.addActionListener(new ActionListener() { |
| |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| Object source = e.getSource(); |
| if (source instanceof JButton) { |
| RequestProcessor.getDefault().post(new Runnable() { |
| |
| @Override |
| public void run() { |
| doImport(); |
| } |
| }); |
| } |
| } |
| }); |
| refreshUI(); |
| } |
| |
| public void remindLater () { |
| Preferences p = NbPreferences.forModule (Installer.class); |
| p.put (Installer.KEY_IMPORT_FROM, srcCluster.toString ()); |
| } |
| |
| public void dontRemind () { |
| Preferences p = NbPreferences.forModule (Installer.class); |
| try { |
| p.clear (); |
| } catch (BackingStoreException ex) { |
| Exceptions.printStackTrace (ex); |
| } |
| } |
| |
| private boolean doImport () { |
| boolean res = true; |
| if (checkedToImport.indexOf (Boolean.TRUE) != -1) { |
| final Collection<UpdateElement> reallyToImport = new HashSet<UpdateElement>(); |
| for (UpdateElement el : toImport) { |
| if (checkedToImport.get(toImport.indexOf(el))) { |
| reallyToImport.add(el); |
| } |
| } |
| if (reallyToImport.size() > 0) { |
| final ProgressHandle handle = ProgressHandleFactory.createHandle(NbBundle.getMessage(ImportManager.class, ("ImportManager.Progress.Name"))); |
| final JComponent progressComp = ProgressHandleFactory.createProgressComponent(handle); |
| final JLabel detailLabel = new JLabel(NbBundle.getMessage(ImportManager.class, "ImportManager.Progress.Label")); |
| detailLabel.setHorizontalAlignment(SwingConstants.LEFT); |
| setProgressComponent(detailLabel, progressComp); |
| |
| try { |
| importer.importPlugins(reallyToImport, srcCluster, dest, handle); |
| } catch (IOException ex) { |
| Exceptions.printStackTrace(ex); |
| } finally { |
| toImport.clear(); |
| checkedToImport.clear(); |
| } |
| |
| try { |
| SwingUtilities.invokeAndWait(new Runnable() { |
| |
| @Override |
| public void run() { |
| detailLabel.setVisible(false); |
| progressComp.setVisible(false); |
| tToImport.setModel(getModel(toImport, checkedToImport)); |
| refreshUI(); |
| } |
| }); |
| } catch (InterruptedException ex) { |
| Exceptions.printStackTrace(ex); |
| } catch (InvocationTargetException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| } |
| } |
| |
| try { |
| dontRemind (); |
| if (checkedToInstall.indexOf (Boolean.TRUE) != -1) { |
| final OperationContainer<InstallSupport> oc = OperationContainer.createForInstall (); |
| for (UpdateElement el : toInstall) { |
| if (checkedToInstall.get (toInstall.indexOf (el))) { |
| OperationContainer.OperationInfo<InstallSupport> info = oc.add (el); |
| if (info != null) { |
| for(UpdateElement required : info.getRequiredElements ()) { |
| if(!required.getUpdateUnit().isPending()) { |
| oc.add (required); |
| } |
| } |
| } |
| } |
| } |
| try { |
| SwingUtilities.invokeAndWait(new Runnable() { |
| |
| @Override |
| public void run() { |
| PluginManager.openInstallWizard(oc, true); |
| SwingUtilities.invokeLater(new Runnable() { |
| |
| @Override |
| public void run() { |
| toInstall.clear(); |
| checkedToInstall.clear(); |
| } |
| }); |
| } |
| }); |
| } catch (InterruptedException ex) { |
| Exceptions.printStackTrace(ex); |
| } catch (InvocationTargetException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| } |
| } finally { |
| try { |
| SwingUtilities.invokeAndWait(new Runnable() { |
| |
| @Override |
| public void run() { |
| tToInstall.setModel(getModel(toInstall, checkedToInstall)); |
| refreshUI(); |
| } |
| }); |
| } catch (InterruptedException ex) { |
| Exceptions.printStackTrace(ex); |
| } catch (InvocationTargetException ex) { |
| Exceptions.printStackTrace(ex); |
| } |
| |
| } |
| return res; |
| |
| } |
| |
| private void setProgressComponent (final JLabel detail, final JComponent progressComponent) { |
| if (SwingUtilities.isEventDispatchThread ()) { |
| setProgressComponentInAwt (detail, progressComponent); |
| } else { |
| SwingUtilities.invokeLater (new Runnable () { |
| @Override |
| public void run () { |
| setProgressComponentInAwt (detail, progressComponent); |
| } |
| }); |
| } |
| } |
| private void setProgressComponentInAwt (JLabel detail, JComponent progressComponent) { |
| assert pProgress != null; |
| assert SwingUtilities.isEventDispatchThread () : "Must be called in EQ."; |
| |
| progressComponent.setMinimumSize (progressComponent.getPreferredSize ()); |
| |
| pProgress.setVisible (true); |
| |
| java.awt.GridBagConstraints gridBagConstraints; |
| |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; |
| gridBagConstraints.insets = new java.awt.Insets(0, 0, 0, 12); |
| pProgress.add(progressComponent, gridBagConstraints); |
| |
| gridBagConstraints = new java.awt.GridBagConstraints(); |
| gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; |
| gridBagConstraints.weightx = 1.0; |
| pProgress.add(detail, gridBagConstraints); |
| |
| validate (); |
| } |
| |
| private TableModel getModel (final List<UpdateElement> plugins, final List<Boolean> checked) { |
| return new AbstractTableModel () { |
| @Override |
| public int getRowCount () { |
| return plugins.size (); |
| } |
| |
| @Override |
| public int getColumnCount () { |
| return 2; |
| } |
| |
| @Override |
| public Object getValueAt (int rowIndex, int columnIndex) { |
| switch (columnIndex) { |
| case 0 : |
| return checked.get (rowIndex); |
| case 1 : |
| return plugins.get (rowIndex).getDisplayName (); |
| } |
| return null; |
| } |
| |
| @Override |
| public Class<?> getColumnClass (int columnIndex) { |
| switch (columnIndex) { |
| case 0 : |
| return Boolean.class; |
| case 1 : |
| return String.class; |
| } |
| return null; |
| } |
| |
| @Override |
| public String getColumnName (int column) { |
| switch (column) { |
| case 0 : |
| return NbBundle.getMessage (ImportManager.class, "ImportNotifier_Install"); |
| case 1 : |
| return NbBundle.getMessage (ImportManager.class, "ImportNotifier_Plugin"); |
| } |
| return null; |
| } |
| |
| @Override |
| public boolean isCellEditable (int rowIndex, int columnIndex) { |
| switch (columnIndex) { |
| case 0 : |
| return true; |
| case 1 : |
| return false; |
| } |
| return false; |
| } |
| |
| @Override |
| public void setValueAt (Object aValue, int rowIndex, int columnIndex) { |
| switch (columnIndex) { |
| case 0 : |
| checked.set (rowIndex, ((Boolean) aValue)); |
| refreshUI (); |
| break; |
| case 1 : |
| assert false : "Name is not editable."; |
| break; |
| } |
| } |
| |
| }; |
| } |
| |
| /** 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() { |
| |
| jScrollPane3 = new javax.swing.JScrollPane(); |
| jTextPane1 = new javax.swing.JTextPane(); |
| lToInstall = new javax.swing.JLabel(); |
| jScrollPane1 = new javax.swing.JScrollPane(); |
| tToInstall = new javax.swing.JTable(); |
| lToImport = new javax.swing.JLabel(); |
| jScrollPane2 = new javax.swing.JScrollPane(); |
| tToImport = new javax.swing.JTable(); |
| lBroken = new javax.swing.JLabel(); |
| jScrollPane4 = new javax.swing.JScrollPane(); |
| tpBroken = new javax.swing.JTextPane(); |
| lDesc = new javax.swing.JLabel(); |
| jSeparator1 = new javax.swing.JSeparator(); |
| jSeparator2 = new javax.swing.JSeparator(); |
| pProgress = new javax.swing.JPanel(); |
| |
| jScrollPane3.setViewportView(jTextPane1); |
| |
| lToInstall.setLabelFor(lToInstall); |
| org.openide.awt.Mnemonics.setLocalizedText(lToInstall, org.openide.util.NbBundle.getMessage(ImportManager.class, "ImportManager.lToInstall.text")); // NOI18N |
| |
| tToInstall.setModel(getModel (toInstall, checkedToInstall)); |
| tToInstall.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS); |
| tToInstall.setOpaque(false); |
| jScrollPane1.setViewportView(tToInstall); |
| |
| lToImport.setLabelFor(tToImport); |
| org.openide.awt.Mnemonics.setLocalizedText(lToImport, org.openide.util.NbBundle.getMessage(ImportManager.class, "ImportManager.lToImport.text")); // NOI18N |
| |
| tToImport.setModel(getModel (toImport, checkedToImport)); |
| tToImport.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_ALL_COLUMNS); |
| tToImport.setOpaque(false); |
| jScrollPane2.setViewportView(tToImport); |
| |
| lBroken.setLabelFor(tpBroken); |
| org.openide.awt.Mnemonics.setLocalizedText(lBroken, org.openide.util.NbBundle.getMessage(ImportManager.class, "ImportManager.lBroken.text")); // NOI18N |
| |
| tpBroken.setEditable(false); |
| tpBroken.setEnabled(false); |
| tpBroken.setOpaque(false); |
| jScrollPane4.setViewportView(tpBroken); |
| |
| lDesc.setFont(lDesc.getFont().deriveFont(lDesc.getFont().getStyle() | java.awt.Font.BOLD)); |
| org.openide.awt.Mnemonics.setLocalizedText(lDesc, org.openide.util.NbBundle.getMessage(ImportManager.class, "ImportManager.lDesc.text", new Object[] {srcCluster})); // NOI18N |
| |
| pProgress.setLayout(new java.awt.GridBagLayout()); |
| |
| javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); |
| this.setLayout(layout); |
| layout.setHorizontalGroup( |
| layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() |
| .addContainerGap() |
| .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) |
| .addComponent(pProgress, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(lToImport, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(jSeparator2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(lToInstall, javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(lDesc, javax.swing.GroupLayout.Alignment.LEADING) |
| .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(jSeparator1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE) |
| .addComponent(lBroken, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 688, Short.MAX_VALUE)) |
| .addContainerGap()) |
| ); |
| layout.setVerticalGroup( |
| layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) |
| .addGroup(layout.createSequentialGroup() |
| .addComponent(lDesc) |
| .addGap(7, 7, 7) |
| .addComponent(lToInstall) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(lToImport) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 158, Short.MAX_VALUE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(jSeparator2, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(lBroken) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE) |
| .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) |
| .addComponent(pProgress, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE) |
| .addContainerGap()) |
| ); |
| }// </editor-fold>//GEN-END:initComponents |
| |
| |
| // Variables declaration - do not modify//GEN-BEGIN:variables |
| private javax.swing.JScrollPane jScrollPane1; |
| private javax.swing.JScrollPane jScrollPane2; |
| private javax.swing.JScrollPane jScrollPane3; |
| private javax.swing.JScrollPane jScrollPane4; |
| private javax.swing.JSeparator jSeparator1; |
| private javax.swing.JSeparator jSeparator2; |
| private javax.swing.JTextPane jTextPane1; |
| private javax.swing.JLabel lBroken; |
| private javax.swing.JLabel lDesc; |
| private javax.swing.JLabel lToImport; |
| private javax.swing.JLabel lToInstall; |
| private javax.swing.JPanel pProgress; |
| private javax.swing.JTable tToImport; |
| private javax.swing.JTable tToInstall; |
| private javax.swing.JTextPane tpBroken; |
| // End of variables declaration//GEN-END:variables |
| |
| private void refreshUI () { |
| lToImport.setEnabled (toImport.size () > 0); |
| tToImport.setEnabled (toImport.size () > 0); |
| |
| lToInstall.setEnabled (toInstall.size () > 0); |
| tToInstall.setEnabled (toInstall.size () > 0); |
| |
| TableColumn activeColumn = tToImport.getColumnModel ().getColumn (0); |
| activeColumn.setMaxWidth (tToImport.getTableHeader ().getHeaderRect (0).width); |
| activeColumn = tToInstall.getColumnModel ().getColumn (0); |
| activeColumn.setMaxWidth (tToInstall.getTableHeader ().getHeaderRect (0).width); |
| |
| if (bImport != null) { |
| bImport.setEnabled (checkedToInstall.indexOf (Boolean.TRUE) != -1 || checkedToImport.indexOf (Boolean.TRUE) != -1); |
| } |
| } |
| |
| } |