--- a/autoupdate.ui/apichanges.xml +++ a/autoupdate.ui/apichanges.xml @@ -56,6 +56,27 @@ + + + PluginManager.install + + + + + +

+ PluginManager ands its + installSingle + and install + shows standard UI for easy installation of single plugin based + on codenamebase. +

+
+ + +
PluginManager.openInstallWizard --- a/autoupdate.ui/manifest.mf +++ a/autoupdate.ui/manifest.mf @@ -2,6 +2,6 @@ OpenIDE-Module: org.netbeans.modules.autoupdate.ui OpenIDE-Module-Install: org/netbeans/modules/autoupdate/ui/actions/Installer.class OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/autoupdate/ui/resources/Bundle.properties -OpenIDE-Module-Specification-Version: 1.34 +OpenIDE-Module-Specification-Version: 1.35 AutoUpdate-Show-In-Client: false AutoUpdate-Essential-Module: true --- a/autoupdate.ui/nbproject/project.xml +++ a/autoupdate.ui/nbproject/project.xml @@ -6,6 +6,15 @@ org.netbeans.modules.autoupdate.ui + org.netbeans.api.annotations.common + + + + 1 + 1.19 + + + org.netbeans.api.progress --- a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java +++ a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java @@ -0,0 +1,417 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2013 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2013 Sun Microsystems, Inc. + */ +package org.netbeans.modules.autoupdate.ui; + +import java.awt.Dialog; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.swing.JButton; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import org.netbeans.api.autoupdate.InstallSupport; +import org.netbeans.api.autoupdate.OperationContainer; +import org.netbeans.api.autoupdate.OperationException; +import org.netbeans.api.autoupdate.OperationSupport; +import org.netbeans.api.autoupdate.OperationSupport.Restarter; +import org.netbeans.api.autoupdate.UpdateElement; +import org.netbeans.api.autoupdate.UpdateManager; +import org.netbeans.api.autoupdate.UpdateUnit; +import org.netbeans.api.autoupdate.UpdateUnitProvider; +import org.netbeans.api.autoupdate.UpdateUnitProviderFactory; +import org.netbeans.api.options.OptionsDisplayer; +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.util.NbBundle.Messages; +import org.openide.util.RequestProcessor; +import static org.netbeans.modules.autoupdate.ui.Bundle.*; + +/** + * + * @author Jesse Glick + * @author Jan Lahoda + * @author Petr Hejl + */ +public class ModuleInstallerSupport { + private static RequestProcessor RP = new RequestProcessor(ModuleInstallerSupport.class.getName(), 1); + private static final Logger LOG = Logger.getLogger(ModuleInstallerSupport.class.getName()); + + @Messages({ + "searching_handle_single=Searching for \"{0}\" module on NetBeans plugin portal...", + "resolve_title_single=Resolve \"{0}\" Reference Problem", + "nodownload_header_single=\"{0}\" module has not been downloaded", + "nodownload_message_single=You can try to download \"{0}\" module again", + "active_handle_single=Activating {0}", + + "searching_handle=Searching for modules on NetBeans plugin portal...", + "resolve_title=Resolve Reference Problem", + "nodownload_header=Modules have not been downloaded", + "nodownload_message=You can try to download modules again", + "active_handle=Activating modules", + + "networkproblem_header=Unable to connect to the NetBeans plugin portal", + "networkproblem_message=Check your proxy settings or try again later. " + + "The server may be unavailable at the moment. " + + "You may also want to make sure that your firewall is not blocking network traffic.", + "proxy_button=&Proxy Settings...", + "tryagain_button=Try &Again" + }) + + private final Object[] closingOptions; + + private Object[] fullClosingOptions; + private JButton tryAgain; + private JButton proxySettings; + + public ModuleInstallerSupport(Object... alternativeOptions) { + this.closingOptions = alternativeOptions.clone(); + } + + public Object installPlugins(final String displayName, Set cnbs) throws OperationException { + Collection units = findModules(cnbs); + if (units == null) { + final String searchMessage = displayName != null + ? searching_handle_single(displayName) : searching_handle(); + final String resolveTitle = displayName != null + ? resolve_title_single(displayName) : resolve_title(); + + final ProgressHandle handle = ProgressHandleFactory.createHandle(searchMessage); + initButtons(); + final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searchMessage), + ProgressHandleFactory.createProgressComponent(handle)), resolveTitle, true, null); + handle.setInitialDelay(0); + handle.start(); + searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION}); + searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE); + final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching); + RP.post(new Runnable() { + + @Override + public void run() { + // May be first start, when no update lists have yet been downloaded. + try { + for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) { + p.refresh(handle, true); + } + // close searching + dlg.dispose(); + } catch (IOException ex) { + LOG.log(Level.FINE, ex.getMessage(), ex); + if (!dlg.isVisible()) { + LOG.fine("dialog not visible => do nothing"); + return; + } + DialogDescriptor networkProblem = new DialogDescriptor( + problemPanel(resolveTitle, networkproblem_message()), // message + networkproblem_header(), // title + true, // modal + null); + networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION}); + networkProblem.setAdditionalOptions(closingOptions); + networkProblem.setClosingOptions(fullClosingOptions); + networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); + Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); + networkProblemDialog.setVisible(true); + Object answer = networkProblem.getValue(); + if (NotifyDescriptor.CANCEL_OPTION.equals(answer) + || Arrays.asList(closingOptions).contains(answer) + || answer.equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */ ) { + LOG.fine("cancel network problem dialog"); + searching.setValue(answer); + dlg.dispose(); + } else if (tryAgain.equals(answer)) { + LOG.fine("try again searching"); + RP.post(this); + } else { + assert false : "Unknown " + answer; + } + } + } + }); + dlg.setVisible(true); + handle.finish(); + if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) + || searching.getValue().equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */) { + LOG.log(Level.FINE, "user canceled searching for {0}", cnbs); + return showNoDownloadDialog(displayName, cnbs); + } else if (Arrays.asList(closingOptions).contains(searching.getValue())){ + return searching.getValue(); + } + units = findModules(cnbs); + if (units == null) { + LOG.log(Level.FINE, "could not find {0} on any update site", cnbs); + return showNoDownloadDialog(displayName, cnbs); + } + } + + List toHandle = new ArrayList(units); + OperationContainer oc = null; + + for (Iterator it = toHandle.iterator(); it.hasNext(); ) { + UpdateUnit unit = it.next(); + + // check if module installed + if (unit.getInstalled() != null) { + if (LOG.isLoggable(Level.FINE)) { + LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled()); + } + if (unit.getInstalled().isEnabled()) { + it.remove(); + continue; + } else { + if (oc == null) { + oc = OperationContainer.createForEnable(); + } + if (!oc.canBeAdded(unit, unit.getInstalled())) { + throw new OperationException(OperationException.ERROR_TYPE.ENABLE, + "could not add " + unit.getInstalled() + " for activation"); + } + for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) { + oc.add(req); + } + it.remove(); + continue; + } + } + } + + if (oc != null) { + ProgressHandle activeHandle = ProgressHandleFactory.createHandle( + displayName != null ? active_handle_single(displayName) : active_handle()); + Restarter restarter = oc.getSupport().doOperation(activeHandle); + assert restarter == null : "No Restater need to make units active"; + } + + if (toHandle.isEmpty()) { + return null; + } + + OperationContainer ocInstall = OperationContainer.createForInstall(); + for (Iterator it = toHandle.iterator(); it.hasNext(); ) { + UpdateUnit unit = it.next(); + + List updates = unit.getAvailableUpdates(); + if (updates.isEmpty()) { + throw new OperationException(OperationException.ERROR_TYPE.INSTALL, "no updates for " + unit); + } + + UpdateElement element = updates.get(0); + if (!ocInstall.canBeAdded(unit, element)) { + throw new OperationException(OperationException.ERROR_TYPE.INSTALL, "could not add " + element + " to updates"); + } + for (UpdateElement req : ocInstall.add(element).getRequiredElements()) { + ocInstall.add(req); + } + it.remove(); + } + assert toHandle.isEmpty() : "These unit were not handled " + toHandle; + + if (!PluginManager.openInstallWizard(ocInstall)) { + LOG.fine("user canceled PM"); + return showNoDownloadDialog(displayName, cnbs); + } + return null; + } + + private Collection findModules(Set cnbs) { + List ret = new ArrayList(cnbs.size()); + for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) { + if (cnbs.contains(unit.getCodeName())) { + ret.add(unit); + if (ret.size() == cnbs.size()) { + break; + } + } + } + if (ret.size() == cnbs.size()) { + return ret; + } + return null; + } + + private void initButtons() { + if (tryAgain != null) { + return ; + } + tryAgain = new JButton(); + proxySettings = new JButton(); + Mnemonics.setLocalizedText(tryAgain, tryagain_button()); + Mnemonics.setLocalizedText(proxySettings, proxy_button()); + proxySettings.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + LOG.fine("show proxy options"); + OptionsDisplayer.getDefault().open("General"); // NOI18N + } + }); + fullClosingOptions = new Object[closingOptions.length + 2]; + System.arraycopy(closingOptions, 0, fullClosingOptions, 0, closingOptions.length); + fullClosingOptions[fullClosingOptions.length - 2] = tryAgain; + fullClosingOptions[fullClosingOptions.length - 1] = NotifyDescriptor.CANCEL_OPTION; + } + + private Object showNoDownloadDialog(String displayName, Set cnbs) throws OperationException { + DialogDescriptor networkProblem; + if (displayName != null) { + networkProblem = new DialogDescriptor( + problemPanel(nodownload_header_single(displayName), nodownload_message_single(displayName)), // message + resolve_title_single(displayName), // title + true, // modal + null); + } else { + networkProblem = new DialogDescriptor( + problemPanel(nodownload_header(), nodownload_message()), // message + resolve_title(), // title + true, // modal + null); + } + initButtons(); + networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); + networkProblem.setAdditionalOptions(closingOptions); + networkProblem.setClosingOptions(fullClosingOptions); + networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); + Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); + networkProblemDialog.setVisible(true); + Object answer = networkProblem.getValue(); + if (NotifyDescriptor.CANCEL_OPTION.equals(answer) + || Arrays.asList(closingOptions).contains(answer) + || answer.equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */ ) { + LOG.fine("cancel no download dialog"); + //throw new InterruptedException("user canceled download & install JUnit"); + return answer; + } else if (tryAgain.equals(answer)) { + LOG.fine("try again download()"); + return installPlugins(displayName, cnbs); + } else { + assert false : "Unknown " + answer; + } + assert false : "Unknown " + answer; + return NotifyDescriptor.DEFAULT_OPTION; + } + + private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) { + JPanel panel = new JPanel(); + progressLabel.setLabelFor(progressComponent); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); + panel.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(96, 96, 96) + .addComponent(progressLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(109, Short.MAX_VALUE)) + ); + return panel; + } + + private static JPanel problemPanel(String header, String message) { + JPanel panel = new JPanel(); + JLabel jLabel1 = new javax.swing.JLabel(); + JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); + JTextArea jTextArea1 = new javax.swing.JTextArea(); + + jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD)); + jLabel1.setText(header); + + jTextArea1.setColumns(20); + jTextArea1.setEditable(false); + jTextArea1.setLineWrap(true); + jTextArea1.setWrapStyleWord(true); + jTextArea1.setRows(5); + jTextArea1.setText(message); + jTextArea1.setOpaque(false); + jScrollPane1.setViewportView(jTextArea1); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); + panel.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addGap(107, 107, 107))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(jLabel1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE) + .addGap(82, 82, 82)) + ); + return panel; + } + +} + --- a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java +++ a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java @@ -42,19 +42,30 @@ package org.netbeans.modules.autoupdate.ui.api; +import java.util.Collections; import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.netbeans.api.annotations.common.CheckForNull; +import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.autoupdate.InstallSupport; import org.netbeans.api.autoupdate.OperationContainer; import org.netbeans.api.autoupdate.OperationContainer.OperationInfo; +import org.netbeans.api.autoupdate.OperationException; import org.netbeans.api.autoupdate.UpdateManager; +import org.netbeans.api.autoupdate.UpdateUnit; +import org.netbeans.modules.autoupdate.ui.ModuleInstallerSupport; import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizard; import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizardModel; import org.netbeans.modules.autoupdate.ui.wizards.OperationWizardModel.OperationType; +import org.openide.NotifyDescriptor; +import org.openide.util.Parameters; /** Access to UI features of PluginManager that can be useful in other modules - * as well. + * as well. * @since 1.21 - * + * * @author Jirka Rechtacek */ public final class PluginManager { @@ -63,10 +74,13 @@ /** Open standard dialog for installing set of modules. Shows it to the user, * asks for confirmation, license acceptance, etc. The whole operation requires - * AWT dispatch thread access (to show the dialog) and blocks + * AWT dispatch thread access (to show the dialog) and blocks * (until the user clicks through), so either call from AWT dispatch thread * directly, or be sure you hold no locks and block no progress of other * threads to avoid deadlocks. + *

+ * Single module installation can be handled easily by + * {@link #installSingle(java.lang.String, java.lang.String, java.lang.Object[])}.

 {@link OperationContainer} container = OperationContainer.createForInstall();
 for ({@link UpdateUnit} u : {@link UpdateManager#getUpdateUnits(org.netbeans.api.autoupdate.UpdateManager.TYPE[]) UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)}) {
@@ -79,10 +93,12 @@ 
 }
 PluginManager.openInstallWizard(container);
 
- * + * * @param container the container with list of modules for install - * @return true if all the requested modules were successfullly installed, + * @return true if all the requested modules were successfullly installed, * false otherwise. + * @see #installSingle(java.lang.String, java.lang.String, java.lang.Object[]) + * @see #install(java.util.Set, java.lang.Object[]) */ public static boolean openInstallWizard(OperationContainer container) { if (container == null) { @@ -100,4 +116,75 @@ OperationType doOperation = info.getUpdateUnit ().getInstalled () == null ? OperationType.INSTALL : OperationType.UPDATE; return new InstallUnitWizard ().invokeWizard (new InstallUnitWizardModel (doOperation, container), false); } + + /** Open standard dialog for installing a module including declared dependencies. + * Shows it to the user, asks for confirmation, license acceptance, etc. + * The whole operation requires AWT dispatch thread access (to show the dialog) + * and blocks (until the user clicks through), so either call from AWT dispatch + * thread directly, or be sure you hold no locks and block no progress of other + * threads to avoid deadlocks. + * + * @param codenamebase the codenamebase of module to install + * @param displayName the display name of the module + * @param alternativeOptions alternative options possibly displayed in error + * dialog user may choose if it is not possible to install the plugin; + * if chosen the option is return value of this method + * @return null if the module has been successfully installed + * and/or activated, otherwise it returns the options user has + * selected in problem dialog, typically {@link NotifyDescriptor#DEFAULT_OPTION} + * (on esc), {@link NotifyDescriptor#CANCEL_OPTION} or + * any of alternativeOptions. + * @since 1.35 + * @see #install(java.util.Set, java.lang.Object[]) + */ + @CheckForNull + public static Object installSingle(@NonNull String codenamebase, @NonNull String displayName, + @NonNull Object... alternativeOptions) { + Parameters.notNull("cnb", codenamebase); + Parameters.notNull("displayName", displayName); + Parameters.notNull("alternativeOptions", alternativeOptions); + + try { + return new ModuleInstallerSupport(alternativeOptions).installPlugins(displayName, Collections.singleton(codenamebase)); + } catch (OperationException ex) { + Logger.getLogger(PluginManager.class.getName()).log(Level.WARNING, null, ex); + } + return NotifyDescriptor.DEFAULT_OPTION; + } + + /** Open standard dialog for installing modules including declared dependencies. + * Shows it to the user, asks for confirmation, license acceptance, etc. + * The whole operation requires AWT dispatch thread access (to show the dialog) + * and blocks (until the user clicks through), so either call from AWT dispatch + * thread directly, or be sure you hold no locks and block no progress of other + * threads to avoid deadlocks. + * + * @param codenamebases the codenamebases of modules to install; must contain at least + * one codenamebase + * @param alternativeOptions alternative options possibly displayed in error + * dialog user may choose if it is not possible to install the plugin; + * if chosen the option is return value of this method + * @return null if all the requested modules have been successfully + * installed and/or activated, otherwise it returns the options user has + * selected in problem dialog, typically {@link NotifyDescriptor#DEFAULT_OPTION} + * (on esc), {@link NotifyDescriptor#CANCEL_OPTION} or + * any of alternativeOptions. + * @throws IllegalArgumentException if the codenamebases is empty + * @since 1.35 + */ + @CheckForNull + public static Object install(@NonNull Set codenamebases, @NonNull Object... alternativeOptions) { + Parameters.notNull("cnb", codenamebases); + Parameters.notNull("alternativeOptions", alternativeOptions); + if (codenamebases.isEmpty()) { + throw new IllegalArgumentException("No plugins to install"); + } + + try { + return new ModuleInstallerSupport(alternativeOptions).installPlugins(null, codenamebases); + } catch (OperationException ex) { + Logger.getLogger(PluginManager.class.getName()).log(Level.WARNING, null, ex); + } + return NotifyDescriptor.DEFAULT_OPTION; + } } --- a/code.analysis/nbproject/project.xml +++ a/code.analysis/nbproject/project.xml @@ -33,19 +33,11 @@
- org.netbeans.modules.autoupdate.services - - - - 1.29 - - - org.netbeans.modules.autoupdate.ui - 1.26 + 1.35 --- a/code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java +++ a/code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java @@ -1,330 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2011 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2011 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.analysis; - -import java.awt.event.ActionEvent; -import org.netbeans.api.autoupdate.OperationSupport; -import org.netbeans.api.autoupdate.OperationSupport.Restarter; -import org.netbeans.api.options.OptionsDisplayer; -import javax.swing.JButton; -import javax.swing.JTextArea; -import javax.swing.JPanel; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.awt.Dialog; -import java.awt.event.ActionListener; -import javax.swing.JComponent; -import javax.swing.JLabel; -import org.openide.DialogDisplayer; -import java.io.IOException; -import java.util.List; -import javax.swing.JScrollPane; -import org.netbeans.api.autoupdate.InstallSupport; -import org.netbeans.api.autoupdate.OperationContainer; -import org.netbeans.api.autoupdate.UpdateElement; -import org.netbeans.api.autoupdate.UpdateManager; -import org.netbeans.api.autoupdate.UpdateUnit; -import org.netbeans.api.autoupdate.UpdateUnitProvider; -import org.netbeans.api.autoupdate.UpdateUnitProviderFactory; -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.NotifyDescriptor; -import org.openide.awt.Mnemonics; -import org.openide.util.NbBundle.Messages; -import org.openide.util.RequestProcessor; -import static org.netbeans.modules.analysis.Bundle.*; - -/** - * Copied and adjusted from the JUnitLibraryDownloader - */ -public class ModuleInstallerSupport { - private static RequestProcessor RP = new RequestProcessor(ModuleInstallerSupport.class.getName(), 1); - private static final Logger LOG = Logger.getLogger(ModuleInstallerSupport.class.getName()); - - @Messages({ - "searching_handle=Searching for \"{0}\" library on NetBeans plugin portal...", - "resolve_title=Resolve \"{0}\" Reference Problem", - "networkproblem_header=Unable to connect to the NetBeans plugin portal", - "networkproblem_message=Check your proxy settings or try again later. " - + "The server may be unavailable at the moment. " - + "You may also want to make sure that your firewall is not blocking network traffic.", - "proxy_button=&Proxy Settings...", - "tryagain_button=Try &Again", - "nodownload_header=\"{0}\" module has not been downloaded", - "nodownload_message=You can try to download \"{0}\" module again", - "active_handle=Activating {0}" - }) - - private JButton tryAgain; - private JButton proxySettings; - - @SuppressWarnings("SleepWhileInLoop") - public boolean download(String cnb, final String displayName) throws Exception { - UpdateUnit unit = findModule(cnb); - if (unit == null) { - final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle(displayName)); - initButtons(); - final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)), - ProgressHandleFactory.createProgressComponent(handle)), resolve_title(displayName), true, null); - handle.setInitialDelay (0); - handle.start (); - searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION}); - searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE); - final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching); - RP.post(new Runnable() { - - @Override - public void run() { - // May be first start, when no update lists have yet been downloaded. - try { - for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) { - p.refresh(handle, true); - } - // close searching - dlg.dispose(); - } catch (IOException ex) { - LOG.log(Level.FINE, ex.getMessage(), ex); - if (! dlg.isVisible()) { - LOG.fine("dialog not visible => do nothing"); - return ; - } - DialogDescriptor networkProblem = new DialogDescriptor( - problemPanel(resolve_title(displayName), networkproblem_message()), // message - networkproblem_header(), // title - true, // modal - null); - networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); - Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); - networkProblemDialog.setVisible(true); - Object answer = networkProblem.getValue(); - if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) { - LOG.fine("cancel network problem dialog"); - searching.setValue(answer); - dlg.dispose(); - } else if (tryAgain.equals(answer)) { - LOG.fine("try again searching"); - RP.post(this); - assert false : "Unknown " + answer; - } - } - } - }); - dlg.setVisible(true); - handle.finish(); - if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) || searching.getValue().equals(-1) /* escape */) { - LOG.log(Level.FINE, "user canceled searching for {0}", cnb); - return showNoDownloadDialog(cnb, displayName); - } - unit = findModule(cnb); - if (unit == null) { - LOG.log(Level.FINE, "could not find {0} on any update site", cnb); - return showNoDownloadDialog(cnb, displayName); - } - } - // check if module installed - if (unit.getInstalled() != null) { - LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled()); - if (unit.getInstalled().isEnabled()) { - throw new Exception(unit.getInstalled() + " already installed and active"); - } else { - // activate it - OperationContainer oc = OperationContainer.createForEnable(); - if (!oc.canBeAdded(unit, unit.getInstalled())) { - throw new Exception("could not add " + unit.getInstalled() + " for activation"); - } - for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) { - oc.add(req); - } - ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle(displayName)); - Restarter restarter = oc.getSupport().doOperation(activeHandle); - assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active"; - // XXX new library & build.properties apparently do not show up immediately... how to listen properly? - return true; - } - } - List updates = unit.getAvailableUpdates(); - if (updates.isEmpty()) { - throw new Exception("no updates for " + unit); - } - OperationContainer oc = OperationContainer.createForInstall(); - UpdateElement element = updates.get(0); - if (!oc.canBeAdded(unit, element)) { - throw new Exception("could not add " + element + " to updates"); - } - for (UpdateElement req : oc.add(element).getRequiredElements()) { - oc.add(req); - } - if (!PluginManager.openInstallWizard(oc)) { - LOG.fine("user canceled PM"); - return showNoDownloadDialog(cnb, displayName); - } - return true; - } - - private UpdateUnit findModule(String cnb) throws IOException { - for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) { - if (unit.getCodeName().equals(cnb)) { - return unit; - } - } - return null; - } - - private void initButtons() { - if (tryAgain != null) { - return ; - } - tryAgain = new JButton(); - proxySettings = new JButton(); - Mnemonics.setLocalizedText(tryAgain, tryagain_button()); - Mnemonics.setLocalizedText(proxySettings, proxy_button()); - proxySettings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - LOG.fine("show proxy options"); - OptionsDisplayer.getDefault().open("General"); // NOI18N - } - }); - } - - private boolean showNoDownloadDialog(String cnb, String displayName) throws Exception { - DialogDescriptor networkProblem = new DialogDescriptor( - problemPanel(nodownload_header(displayName), nodownload_message(displayName)), // message - resolve_title(displayName), // title - true, // modal - null); - initButtons(); - networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); - Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); - networkProblemDialog.setVisible(true); - Object answer = networkProblem.getValue(); - if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) { - LOG.fine("cancel no download dialog"); - //throw new InterruptedException("user canceled download & install JUnit"); - return false; - } else if (tryAgain.equals(answer)) { - LOG.fine("try again download()"); - return download(cnb, displayName); - } else { - assert false : "Unknown " + answer; - } - assert false : "Unknown " + answer; - return false; - } - - private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) { - JPanel panel = new JPanel(); - progressLabel.setLabelFor(progressComponent); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); - panel.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(96, 96, 96) - .addComponent(progressLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(109, Short.MAX_VALUE)) - ); - return panel; - } - - private static JPanel problemPanel(String header, String message) { - JPanel panel = new JPanel(); - JLabel jLabel1 = new javax.swing.JLabel(); - JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); - JTextArea jTextArea1 = new javax.swing.JTextArea(); - - jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD)); - jLabel1.setText(header); - - jTextArea1.setColumns(20); - jTextArea1.setEditable(false); - jTextArea1.setLineWrap(true); - jTextArea1.setWrapStyleWord(true); - jTextArea1.setRows(5); - jTextArea1.setText(message); - jTextArea1.setOpaque(false); - jScrollPane1.setViewportView(jTextArea1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); - panel.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addGap(107, 107, 107))) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE) - .addGap(82, 82, 82)) - ); - return panel; - } - -} --- a/code.analysis/src/org/netbeans/modules/analysis/Utils.java +++ a/code.analysis/src/org/netbeans/modules/analysis/Utils.java @@ -45,7 +45,7 @@ import java.util.HashSet; import java.util.Set; import org.netbeans.modules.analysis.spi.Analyzer.MissingPlugin; -import org.openide.util.Exceptions; +import org.netbeans.modules.autoupdate.ui.api.PluginManager; /** * @@ -57,11 +57,7 @@ Set plugins = new HashSet(inPlugins); for (MissingPlugin missing : plugins) { - try { - new ModuleInstallerSupport().download(SPIAccessor.ACCESSOR.getCNB(missing), SPIAccessor.ACCESSOR.getDisplayName(missing)); - } catch (Exception ex) { - Exceptions.printStackTrace(ex); - } + PluginManager.installSingle(SPIAccessor.ACCESSOR.getCNB(missing), SPIAccessor.ACCESSOR.getDisplayName(missing)); } } } --- a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java +++ a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java @@ -41,6 +41,7 @@ */ package org.netbeans.modules.findbugs.installer; +import org.netbeans.modules.autoupdate.ui.api.PluginManager; import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; @@ -95,11 +96,7 @@ @Messages("FindBugs_Library=FindBugs Library") private void installActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_installActionPerformed - try { - new ModuleInstallerSupport().download("org.netbeans.modules.findbugs", Bundle.FindBugs_Library()); - } catch (Exception ex) { - Exceptions.printStackTrace(ex); - } + PluginManager.installSingle("org.netbeans.modules.findbugs", Bundle.FindBugs_Library()); }//GEN-LAST:event_installActionPerformed void load() { --- a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java +++ a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java @@ -1,331 +0,0 @@ -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright 2011 Oracle and/or its affiliates. All rights reserved. - * - * Oracle and Java are registered trademarks of Oracle and/or its affiliates. - * Other names may be trademarks of their respective owners. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common - * Development and Distribution License("CDDL") (collectively, the - * "License"). You may not use this file except in compliance with the - * License. You can obtain a copy of the License at - * http://www.netbeans.org/cddl-gplv2.html - * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the - * specific language governing permissions and limitations under the - * License. When distributing the software, include this License Header - * Notice in each file and include the License file at - * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the GPL Version 2 section of the License file that - * accompanied this code. If applicable, add the following below the - * License Header, with the fields enclosed by brackets [] replaced by - * your own identifying information: - * "Portions Copyrighted [year] [name of copyright owner]" - * - * If you wish your version of this file to be governed by only the CDDL - * or only the GPL Version 2, indicate your decision by adding - * "[Contributor] elects to include this software in this distribution - * under the [CDDL or GPL Version 2] license." If you do not indicate a - * single choice of license, a recipient has the option to distribute - * your version of this file under either the CDDL, the GPL Version 2 or - * to extend the choice of license to its licensees as provided above. - * However, if you add GPL Version 2 code and therefore, elected the GPL - * Version 2 license, then the option applies only if the new code is - * made subject to such option by the copyright holder. - * - * Contributor(s): - * - * Portions Copyrighted 2011 Sun Microsystems, Inc. - */ - -package org.netbeans.modules.findbugs.installer; - -import java.awt.event.ActionEvent; -import org.netbeans.api.autoupdate.OperationSupport; -import org.netbeans.api.autoupdate.OperationSupport.Restarter; -import org.netbeans.api.options.OptionsDisplayer; -import javax.swing.JButton; -import javax.swing.JTextArea; -import javax.swing.JPanel; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.awt.Dialog; -import java.awt.event.ActionListener; -import javax.swing.JComponent; -import javax.swing.JLabel; -import org.openide.DialogDisplayer; -import java.io.IOException; -import java.util.List; -import javax.swing.JScrollPane; -import org.netbeans.api.autoupdate.InstallSupport; -import org.netbeans.api.autoupdate.OperationContainer; -import org.netbeans.api.autoupdate.UpdateElement; -import org.netbeans.api.autoupdate.UpdateManager; -import org.netbeans.api.autoupdate.UpdateUnit; -import org.netbeans.api.autoupdate.UpdateUnitProvider; -import org.netbeans.api.autoupdate.UpdateUnitProviderFactory; -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.NotifyDescriptor; -import org.openide.awt.Mnemonics; -import org.openide.util.NbBundle.Messages; -import org.openide.util.RequestProcessor; -import static org.netbeans.modules.findbugs.installer.Bundle.*; - -/** - * Copied and adjusted from the JUnitLibraryDownloader - */ -public class ModuleInstallerSupport { - private static RequestProcessor RP = new RequestProcessor(ModuleInstallerSupport.class.getName(), 1); - private static final Logger LOG = Logger.getLogger(ModuleInstallerSupport.class.getName()); - - @Messages({ - "searching_handle=Searching for \"{0}\" library on NetBeans plugin portal...", - "resolve_title=Resolve \"{0}\" Reference Problem", - "networkproblem_header=Unable to connect to the NetBeans plugin portal", - "networkproblem_message=Check your proxy settings or try again later. " - + "The server may be unavailable at the moment. " - + "You may also want to make sure that your firewall is not blocking network traffic.", - "proxy_button=&Proxy Settings...", - "tryagain_button=Try &Again", - "nodownload_header=\"{0}\" module has not been downloaded", - "nodownload_message=You can try to download \"{0}\" module again", - "active_handle=Activating {0}" - }) - - private JButton tryAgain; - private JButton proxySettings; - - @SuppressWarnings("SleepWhileInLoop") - public boolean download(String cnb, final String displayName) throws Exception { - UpdateUnit unit = findModule(cnb); - if (unit == null) { - final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle(displayName)); - initButtons(); - final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)), - ProgressHandleFactory.createProgressComponent(handle)), resolve_title(displayName), true, null); - handle.setInitialDelay (0); - handle.start (); - searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION}); - searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE); - final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching); - RP.post(new Runnable() { - - @Override - public void run() { - // May be first start, when no update lists have yet been downloaded. - try { - for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) { - p.refresh(handle, true); - } - // close searching - dlg.dispose(); - } catch (IOException ex) { - LOG.log(Level.FINE, ex.getMessage(), ex); - if (! dlg.isVisible()) { - LOG.fine("dialog not visible => do nothing"); - return ; - } - DialogDescriptor networkProblem = new DialogDescriptor( - problemPanel(resolve_title(displayName), networkproblem_message()), // message - networkproblem_header(), // title - true, // modal - null); - networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); - Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); - networkProblemDialog.setVisible(true); - Object answer = networkProblem.getValue(); - if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) { - LOG.fine("cancel network problem dialog"); - searching.setValue(answer); - dlg.dispose(); - } else if (tryAgain.equals(answer)) { - LOG.fine("try again searching"); - RP.post(this); - } else { - assert false : "Unknown " + answer; - } - } - } - }); - dlg.setVisible(true); - handle.finish(); - if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) || searching.getValue().equals(-1) /* escape */) { - LOG.log(Level.FINE, "user canceled searching for {0}", cnb); - return showNoDownloadDialog(cnb, displayName); - } - unit = findModule(cnb); - if (unit == null) { - LOG.log(Level.FINE, "could not find {0} on any update site", cnb); - return showNoDownloadDialog(cnb, displayName); - } - } - // check if module installed - if (unit.getInstalled() != null) { - LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled()); - if (unit.getInstalled().isEnabled()) { - throw new Exception(unit.getInstalled() + " already installed and active"); - } else { - // activate it - OperationContainer oc = OperationContainer.createForEnable(); - if (!oc.canBeAdded(unit, unit.getInstalled())) { - throw new Exception("could not add " + unit.getInstalled() + " for activation"); - } - for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) { - oc.add(req); - } - ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle(displayName)); - Restarter restarter = oc.getSupport().doOperation(activeHandle); - assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active"; - // XXX new library & build.properties apparently do not show up immediately... how to listen properly? - return true; - } - } - List updates = unit.getAvailableUpdates(); - if (updates.isEmpty()) { - throw new Exception("no updates for " + unit); - } - OperationContainer oc = OperationContainer.createForInstall(); - UpdateElement element = updates.get(0); - if (!oc.canBeAdded(unit, element)) { - throw new Exception("could not add " + element + " to updates"); - } - for (UpdateElement req : oc.add(element).getRequiredElements()) { - oc.add(req); - } - if (!PluginManager.openInstallWizard(oc)) { - LOG.fine("user canceled PM"); - return showNoDownloadDialog(cnb, displayName); - } - return true; - } - - private UpdateUnit findModule(String cnb) throws IOException { - for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) { - if (unit.getCodeName().equals(cnb)) { - return unit; - } - } - return null; - } - - private void initButtons() { - if (tryAgain != null) { - return ; - } - tryAgain = new JButton(); - proxySettings = new JButton(); - Mnemonics.setLocalizedText(tryAgain, tryagain_button()); - Mnemonics.setLocalizedText(proxySettings, proxy_button()); - proxySettings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - LOG.fine("show proxy options"); - OptionsDisplayer.getDefault().open("General"); // NOI18N - } - }); - } - - private boolean showNoDownloadDialog(String cnb, String displayName) throws Exception { - DialogDescriptor networkProblem = new DialogDescriptor( - problemPanel(nodownload_header(displayName), nodownload_message(displayName)), // message - resolve_title(displayName), // title - true, // modal - null); - initButtons(); - networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); - Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); - networkProblemDialog.setVisible(true); - Object answer = networkProblem.getValue(); - if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) { - LOG.fine("cancel no download dialog"); - //throw new InterruptedException("user canceled download & install JUnit"); - return false; - } else if (tryAgain.equals(answer)) { - LOG.fine("try again download()"); - return download(cnb, displayName); - } else { - assert false : "Unknown " + answer; - } - assert false : "Unknown " + answer; - return false; - } - - private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) { - JPanel panel = new JPanel(); - progressLabel.setLabelFor(progressComponent); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); - panel.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(96, 96, 96) - .addComponent(progressLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(109, Short.MAX_VALUE)) - ); - return panel; - } - - private static JPanel problemPanel(String header, String message) { - JPanel panel = new JPanel(); - JLabel jLabel1 = new javax.swing.JLabel(); - JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); - JTextArea jTextArea1 = new javax.swing.JTextArea(); - - jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD)); - jLabel1.setText(header); - - jTextArea1.setColumns(20); - jTextArea1.setEditable(false); - jTextArea1.setLineWrap(true); - jTextArea1.setWrapStyleWord(true); - jTextArea1.setRows(5); - jTextArea1.setText(message); - jTextArea1.setOpaque(false); - jScrollPane1.setViewportView(jTextArea1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); - panel.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addGap(107, 107, 107))) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE) - .addGap(82, 82, 82)) - ); - return panel; - } - -} --- a/junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java +++ a/junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java @@ -42,42 +42,15 @@ package org.netbeans.modules.junit; -import java.awt.event.ActionEvent; -import org.netbeans.api.autoupdate.OperationSupport; -import org.netbeans.api.autoupdate.OperationSupport.Restarter; -import org.netbeans.api.options.OptionsDisplayer; import javax.swing.JButton; -import javax.swing.JTextArea; -import javax.swing.JPanel; -import java.util.logging.Level; import java.util.logging.Logger; -import java.awt.Dialog; -import java.awt.event.ActionListener; -import javax.swing.JComponent; -import javax.swing.JLabel; -import org.openide.DialogDisplayer; -import java.io.IOException; -import java.util.List; import java.util.concurrent.Callable; -import javax.swing.JScrollPane; -import org.netbeans.api.autoupdate.InstallSupport; -import org.netbeans.api.autoupdate.OperationContainer; -import org.netbeans.api.autoupdate.UpdateElement; -import org.netbeans.api.autoupdate.UpdateManager; -import org.netbeans.api.autoupdate.UpdateUnit; -import org.netbeans.api.autoupdate.UpdateUnitProvider; -import org.netbeans.api.autoupdate.UpdateUnitProviderFactory; -import org.netbeans.api.progress.ProgressHandle; -import org.netbeans.api.progress.ProgressHandleFactory; import org.netbeans.api.project.libraries.Library; import org.netbeans.api.project.libraries.LibraryManager; import org.netbeans.modules.autoupdate.ui.api.PluginManager; import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport.LibraryDefiner; -import org.openide.DialogDescriptor; -import org.openide.NotifyDescriptor; import org.openide.awt.Mnemonics; import org.openide.util.NbBundle.Messages; -import org.openide.util.RequestProcessor; import org.openide.util.lookup.ServiceProvider; import static org.netbeans.modules.junit.Bundle.*; @@ -85,27 +58,11 @@ * Defines JUnit 3.x/4.x libraries by downloading their defining modules. */ @ServiceProvider(service=LibraryDefiner.class) -public class JUnitLibraryDownloader implements LibraryDefiner { - private static RequestProcessor RP = new RequestProcessor(JUnitLibraryDownloader.class.getName(), 1); - private static final Logger LOG = Logger.getLogger(JUnitLibraryDownloader.class.getName()); +public class JUnitLibraryDefiner implements LibraryDefiner { @Messages({ - "searching_handle=Searching for \"junit\" library on NetBeans plugin portal...", - "resolve_title=Resolve \"junit\" Reference Problem", - "networkproblem_header=Unable to connect to the NetBeans plugin portal", - "networkproblem_message=Check your proxy settings or try again later. " - + "The server may be unavailable at the moment. " - + "You may also want to make sure that your firewall is not blocking network traffic. \n\n" - + "If you have the missing \"junit\" library, you can resolve the reference " - + "problem manually using Library Manager.", - "proxy_button=&Proxy Settings...", "library_button=&Library Manager...", - "tryagain_button=Try &Again", - "nodownload_header=\"junit\" library has not been downloaded", - "nodownload_message=You can try to download \"junit\" library again, or \n\n" - + "if you have the missing \"junit\" library, you can resolve the reference " - + "problem manually using Library Manager.", - "active_handle=Activating JUnit" + "library_name=junit" }) public @Override Callable missingLibrary(final String name) { @@ -113,272 +70,26 @@ return null; } return new Callable() { + + @SuppressWarnings("SleepWhileInLoop") public @Override Library call() throws Exception { - return download(name); - } - }; - } - - private JButton libraryManager; - private JButton tryAgain; - private JButton proxySettings; - - @SuppressWarnings("SleepWhileInLoop") - private Library download(String name) throws Exception { - UpdateUnit unit = findJUnitLib(); - if (unit == null) { - final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle()); - initButtons(); - final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle()), - ProgressHandleFactory.createProgressComponent(handle)), resolve_title(), true, null); - handle.setInitialDelay (0); - handle.start (); - searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION}); - searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE); - final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching); - RP.post(new Runnable() { - - @Override - public void run() { - // May be first start, when no update lists have yet been downloaded. - try { - for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) { - p.refresh(handle, true); - } - // close searching - dlg.dispose(); - } catch (IOException ex) { - Logger.getLogger(JUnitLibraryDownloader.class.getName()).log(Level.FINE, ex.getMessage(), ex); - if (! dlg.isVisible()) { - LOG.fine("dialog not visible => do nothing"); - return ; - } - DialogDescriptor networkProblem = new DialogDescriptor( - problemPanel(resolve_title(), networkproblem_message()), // message - networkproblem_header(), // title - true, // modal - null); - networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setAdditionalOptions(new Object[] {libraryManager}); - networkProblem.setClosingOptions(new Object[] {libraryManager, tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); - Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); - networkProblemDialog.setVisible(true); - Object answer = networkProblem.getValue(); - if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) { - LOG.fine("cancel network problem dialog"); - searching.setValue(answer); - dlg.dispose(); - } else if (tryAgain.equals(answer)) { - LOG.fine("try again searching"); - RP.post(this); - } else if (libraryManager.equals(answer)) { - LOG.fine("open library manager"); - searching.setValue(answer); - dlg.dispose(); - } else { - assert false : "Unknown " + answer; - } - } + JButton libraryManager = new JButton(); + Mnemonics.setLocalizedText(libraryManager, library_button()); + Object ret = PluginManager.installSingle("org.netbeans.modules.junitlib", library_name(), libraryManager); + if (libraryManager.equals(ret)) { + throw new Exception("junitlib failed/canceled to install properly, open library manager instaed"); } - }); - dlg.setVisible(true); - handle.finish(); - if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) || searching.getValue().equals(-1) /* escape */) { - LOG.fine("user canceled searching JUnit"); - return showNoDownloadDialog(name); - } else if (libraryManager.equals(searching.getValue())) { - throw new Exception("user canceled searching"); - } - unit = findJUnitLib(); - if (unit == null) { - LOG.fine("could not find junitlib on any update site"); - return showNoDownloadDialog(name); - } - } - // check if JUnit installed - if (unit.getInstalled() != null) { - LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled()); - if (unit.getInstalled().isEnabled()) { - throw new Exception(unit.getInstalled() + " already installed and active"); - } else { - // activate it - OperationContainer oc = OperationContainer.createForEnable(); - if (!oc.canBeAdded(unit, unit.getInstalled())) { - throw new Exception("could not add " + unit.getInstalled() + " for activation"); - } - for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) { - oc.add(req); - } - ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle()); - Restarter restarter = oc.getSupport().doOperation(activeHandle); - assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active"; // XXX new library & build.properties apparently do not show up immediately... how to listen properly? - for (int i = 0; i < 10; i++) { + for (int i = 0; i < 20; i++) { Library lib = LibraryManager.getDefault().getLibrary(name); if (lib != null) { return lib; } Thread.sleep(1000); } - LOG.info("junitlib failed to make active properly"); - return showNoDownloadDialog(name); + return null; } - } - List updates = unit.getAvailableUpdates(); - if (updates.isEmpty()) { - throw new Exception("no updates for " + unit); - } - OperationContainer oc = OperationContainer.createForInstall(); - UpdateElement element = updates.get(0); - if (!oc.canBeAdded(unit, element)) { - throw new Exception("could not add " + element + " to updates"); - } - for (UpdateElement req : oc.add(element).getRequiredElements()) { - oc.add(req); - } - if (!PluginManager.openInstallWizard(oc)) { - LOG.fine("user canceled PM"); - return showNoDownloadDialog(name); - } - // XXX new library & build.properties apparently do not show up immediately... how to listen properly? - for (int i = 0; i < 20; i++) { - Library lib = LibraryManager.getDefault().getLibrary(name); - if (lib != null) { - return lib; - } - Thread.sleep(1000); - } - LOG.info("junitlib failed to install properly"); - return showNoDownloadDialog(name); - } - - private UpdateUnit findJUnitLib() throws IOException { - for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) { - if (unit.getCodeName().equals("org.netbeans.modules.junitlib")) { - return unit; - } - } - return null; - } - - private void initButtons() { - if (libraryManager != null) { - return ; - } - libraryManager = new JButton(); - tryAgain = new JButton(); - proxySettings = new JButton(); - Mnemonics.setLocalizedText(tryAgain, tryagain_button()); - Mnemonics.setLocalizedText(libraryManager, library_button()); - Mnemonics.setLocalizedText(proxySettings, proxy_button()); - proxySettings.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - LOG.fine("show proxy options"); - OptionsDisplayer.getDefault().open("General"); // NOI18N - } - }); - } - - private Library showNoDownloadDialog(String name) throws Exception { - DialogDescriptor networkProblem = new DialogDescriptor( - problemPanel(nodownload_header(), nodownload_message()), // message - resolve_title(), // title - true, // modal - null); - initButtons(); - networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setAdditionalOptions(new Object[] {libraryManager}); - networkProblem.setClosingOptions(new Object[] {libraryManager, tryAgain, NotifyDescriptor.CANCEL_OPTION}); - networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE); - Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem); - networkProblemDialog.setVisible(true); - Object answer = networkProblem.getValue(); - if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) { - LOG.fine("cancel no download dialog"); - //throw new InterruptedException("user canceled download & install JUnit"); - return null; - } else if (tryAgain.equals(answer)) { - LOG.fine("try again download()"); - return download(name); - } else if (libraryManager.equals(answer)) { - LOG.fine("open library manager"); - throw new Exception("junitlib failed/canceled to install properly, open library manager instaed"); - } else { - assert false : "Unknown " + answer; - } - assert false : "Unknown " + answer; - return null; - } - - private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) { - JPanel panel = new JPanel(); - progressLabel.setLabelFor(progressComponent); - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); - panel.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE)) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(96, 96, 96) - .addComponent(progressLabel) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(109, Short.MAX_VALUE)) - ); - return panel; - } - - private static JPanel problemPanel(String header, String message) { - JPanel panel = new JPanel(); - JLabel jLabel1 = new javax.swing.JLabel(); - JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); - JTextArea jTextArea1 = new javax.swing.JTextArea(); - - jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD)); - jLabel1.setText(header); - - jTextArea1.setColumns(20); - jTextArea1.setEditable(false); - jTextArea1.setLineWrap(true); - jTextArea1.setWrapStyleWord(true); - jTextArea1.setRows(5); - jTextArea1.setText(message); - jTextArea1.setOpaque(false); - jScrollPane1.setViewportView(jTextArea1); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel); - panel.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE) - .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addGap(107, 107, 107))) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE) - .addGap(82, 82, 82)) - ); - return panel; + }; } }