This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 196538
Collapse All | Expand All

(-)a/autoupdate.ui/apichanges.xml (+20 lines)
Lines 56-61 Link Here
56
    <!-- ACTUAL CHANGES BEGIN HERE: -->
56
    <!-- ACTUAL CHANGES BEGIN HERE: -->
57
57
58
    <changes>
58
    <changes>
59
        <change id="PluginManager.installPlugin">
60
            <api name="ui"/>
61
            <summary>PluginManager.installPlugin</summary>
62
            <version major="1" minor="35"/>
63
            <date day="13" month="2" year="2013"/>
64
            <author login="phejl"/>
65
            <compatibility addition="yes" binary="compatible" deletion="no"
66
                deprecation="no" semantic="compatible" source="compatible"
67
            />
68
            <description>
69
                <p>
70
                <code>PluginManager</code> ands its
71
                <a href="@TOP@/org/netbeans/modules/autoupdate/ui/api/PluginManager.html#installPlugin(java.lang.String, java.lang.String, java.lang.Object...)">installPlugin</a>
72
                shows standard UI for easy installation of single plugin based
73
                on codenamebase.
74
                </p>
75
            </description>
76
            <class package="org.netbeans.modules.autoupdate.ui.api" name="PluginManager"/>
77
            <issue number="196538"/>
78
        </change>
59
        <change id="PluginManager.openInstallWizard">
79
        <change id="PluginManager.openInstallWizard">
60
            <api name="ui"/>
80
            <api name="ui"/>
61
            <summary>PluginManager.openInstallWizard</summary>
81
            <summary>PluginManager.openInstallWizard</summary>
(-)a/autoupdate.ui/manifest.mf (-1 / +1 lines)
Lines 2-7 Link Here
2
OpenIDE-Module: org.netbeans.modules.autoupdate.ui
2
OpenIDE-Module: org.netbeans.modules.autoupdate.ui
3
OpenIDE-Module-Install: org/netbeans/modules/autoupdate/ui/actions/Installer.class
3
OpenIDE-Module-Install: org/netbeans/modules/autoupdate/ui/actions/Installer.class
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/autoupdate/ui/resources/Bundle.properties
4
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/autoupdate/ui/resources/Bundle.properties
5
OpenIDE-Module-Specification-Version: 1.34
5
OpenIDE-Module-Specification-Version: 1.35
6
AutoUpdate-Show-In-Client: false
6
AutoUpdate-Show-In-Client: false
7
AutoUpdate-Essential-Module: true
7
AutoUpdate-Essential-Module: true
(-)a/autoupdate.ui/nbproject/project.xml (+9 lines)
Lines 6-11 Link Here
6
            <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
6
            <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
7
            <module-dependencies>
7
            <module-dependencies>
8
                <dependency>
8
                <dependency>
9
                    <code-name-base>org.netbeans.api.annotations.common</code-name-base>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
12
                    <run-dependency>
13
                        <release-version>1</release-version>
14
                        <specification-version>1.19</specification-version>
15
                    </run-dependency>
16
                </dependency>
17
                <dependency>
9
                    <code-name-base>org.netbeans.api.progress</code-name-base>
18
                    <code-name-base>org.netbeans.api.progress</code-name-base>
10
                    <build-prerequisite/>
19
                    <build-prerequisite/>
11
                    <compile-dependency/>
20
                    <compile-dependency/>
(-)a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/ModuleInstallerSupport.java (+357 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.autoupdate.ui;
43
44
import java.awt.Dialog;
45
import java.awt.event.ActionEvent;
46
import java.awt.event.ActionListener;
47
import java.io.IOException;
48
import java.util.Arrays;
49
import java.util.List;
50
import java.util.logging.Level;
51
import java.util.logging.Logger;
52
import javax.swing.JButton;
53
import javax.swing.JComponent;
54
import javax.swing.JLabel;
55
import javax.swing.JPanel;
56
import javax.swing.JScrollPane;
57
import javax.swing.JTextArea;
58
import org.netbeans.api.autoupdate.InstallSupport;
59
import org.netbeans.api.autoupdate.OperationContainer;
60
import org.netbeans.api.autoupdate.OperationException;
61
import org.netbeans.api.autoupdate.OperationSupport;
62
import org.netbeans.api.autoupdate.OperationSupport.Restarter;
63
import org.netbeans.api.autoupdate.UpdateElement;
64
import org.netbeans.api.autoupdate.UpdateManager;
65
import org.netbeans.api.autoupdate.UpdateUnit;
66
import org.netbeans.api.autoupdate.UpdateUnitProvider;
67
import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
68
import org.netbeans.api.options.OptionsDisplayer;
69
import org.netbeans.api.progress.ProgressHandle;
70
import org.netbeans.api.progress.ProgressHandleFactory;
71
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
72
import org.openide.DialogDescriptor;
73
import org.openide.DialogDisplayer;
74
import org.openide.NotifyDescriptor;
75
import org.openide.awt.Mnemonics;
76
import org.openide.util.NbBundle.Messages;
77
import org.openide.util.RequestProcessor;
78
import static org.netbeans.modules.autoupdate.ui.Bundle.*;
79
80
/**
81
 *
82
 * @author Jan Lahoda
83
 * @author Petr Hejl
84
 */
85
public class ModuleInstallerSupport  {
86
    private static RequestProcessor RP = new RequestProcessor(ModuleInstallerSupport.class.getName(), 1);
87
    private static final Logger LOG = Logger.getLogger(ModuleInstallerSupport.class.getName());
88
89
    @Messages({
90
        "searching_handle=Searching for \"{0}\" module on NetBeans plugin portal...",
91
        "resolve_title=Resolve \"{0}\" Reference Problem",
92
        "networkproblem_header=Unable to connect  to the NetBeans plugin portal",
93
        "networkproblem_message=Check your proxy settings or try again later. "
94
            + "The server may be unavailable at the moment. "
95
            + "You may also want to make sure that your firewall is not blocking network traffic.",
96
        "proxy_button=&Proxy Settings...",
97
        "tryagain_button=Try &Again",
98
        "nodownload_header=\"{0}\" module has not been downloaded",
99
        "nodownload_message=You can try to download \"{0}\" module again",
100
        "active_handle=Activating {0}"
101
    })
102
103
    private final Object[] closingOptions;
104
105
    private Object[] fullClosingOptions;
106
    private JButton tryAgain;
107
    private JButton proxySettings;
108
109
    public ModuleInstallerSupport(Object... alternativeOptions) {
110
        this.closingOptions = alternativeOptions.clone();
111
    }
112
113
    public Object installPlugin(String cnb, final String displayName) throws OperationException {
114
        UpdateUnit unit = findModule(cnb);
115
        if (unit == null) {
116
            final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle(displayName));
117
            initButtons();
118
            final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)),
119
                    ProgressHandleFactory.createProgressComponent(handle)), resolve_title(displayName), true, null);
120
            handle.setInitialDelay(0);
121
            handle.start();
122
            searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION});
123
            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
124
            final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching);
125
            RP.post(new Runnable() {
126
127
                @Override
128
                public void run() {
129
                    // May be first start, when no update lists have yet been downloaded.
130
                    try {
131
                        for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
132
                            p.refresh(handle, true);
133
                        }
134
                        // close searching
135
                        dlg.dispose();
136
                    } catch (IOException ex) {
137
                        LOG.log(Level.FINE, ex.getMessage(), ex);
138
                        if (!dlg.isVisible()) {
139
                            LOG.fine("dialog not visible => do nothing");
140
                            return;
141
                        }
142
                        DialogDescriptor networkProblem = new DialogDescriptor(
143
                                problemPanel(resolve_title(displayName), networkproblem_message()), // message
144
                                networkproblem_header(), // title
145
                                true, // modal
146
                                null);
147
                        networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION});
148
                        networkProblem.setAdditionalOptions(closingOptions);
149
                        networkProblem.setClosingOptions(fullClosingOptions);
150
                        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
151
                        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
152
                        networkProblemDialog.setVisible(true);
153
                        Object answer = networkProblem.getValue();
154
                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer)
155
                                || Arrays.asList(closingOptions).contains(answer)
156
                                || answer.equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */ ) {
157
                            LOG.fine("cancel network problem dialog");
158
                            searching.setValue(answer);
159
                            dlg.dispose();
160
                        } else if (tryAgain.equals(answer)) {
161
                            LOG.fine("try again searching");
162
                            RP.post(this);
163
                        } else {
164
                            assert false : "Unknown " + answer;
165
                        }
166
                    }
167
                }
168
            });
169
            dlg.setVisible(true);
170
            handle.finish();
171
            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue())
172
                    || searching.getValue().equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */) {
173
                LOG.log(Level.FINE, "user canceled searching for {0}", cnb);
174
                return showNoDownloadDialog(cnb, displayName);
175
            } else if (Arrays.asList(closingOptions).contains(searching.getValue())){
176
                return searching.getValue();
177
            }
178
            unit = findModule(cnb);
179
            if (unit == null) {
180
                LOG.log(Level.FINE, "could not find {0} on any update site", cnb);
181
                return showNoDownloadDialog(cnb, displayName);
182
            }
183
        }
184
        // check if module installed
185
        if (unit.getInstalled() != null) {
186
            if (LOG.isLoggable(Level.FINE)) {
187
                LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled());
188
            }
189
            if (unit.getInstalled().isEnabled()) {
190
                return null;
191
                //throw new Exception(unit.getInstalled() + " already installed and active");
192
            } else {
193
                // activate it
194
                OperationContainer<OperationSupport> oc = OperationContainer.createForEnable();
195
                if (!oc.canBeAdded(unit, unit.getInstalled())) {
196
                    throw new OperationException(OperationException.ERROR_TYPE.ENABLE,
197
                            "could not add " + unit.getInstalled() + " for activation");
198
                }
199
                for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) {
200
                    oc.add(req);
201
                }
202
                ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle(displayName));
203
                Restarter restarter = oc.getSupport().doOperation(activeHandle);
204
                assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active";
205
                return null;
206
            }
207
        }
208
        List<UpdateElement> updates = unit.getAvailableUpdates();
209
        if (updates.isEmpty()) {
210
            throw new OperationException(OperationException.ERROR_TYPE.INSTALL, "no updates for " + unit);
211
        }
212
        OperationContainer<InstallSupport> oc = OperationContainer.createForInstall();
213
        UpdateElement element = updates.get(0);
214
        if (!oc.canBeAdded(unit, element)) {
215
            throw new OperationException(OperationException.ERROR_TYPE.INSTALL, "could not add " + element + " to updates");
216
        }
217
        for (UpdateElement req : oc.add(element).getRequiredElements()) {
218
            oc.add(req);
219
        }
220
        if (!PluginManager.openInstallWizard(oc)) {
221
            LOG.fine("user canceled PM");
222
            return showNoDownloadDialog(cnb, displayName);
223
        }
224
        return null;
225
    }
226
227
    private UpdateUnit findModule(String cnb) {
228
        for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
229
            if (unit.getCodeName().equals(cnb)) {
230
                return unit;
231
            }
232
        }
233
        return null;
234
    }
235
236
    private void initButtons() {
237
        if (tryAgain != null) {
238
            return ;
239
        }
240
        tryAgain = new JButton();
241
        proxySettings = new JButton();
242
        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
243
        Mnemonics.setLocalizedText(proxySettings, proxy_button());
244
        proxySettings.addActionListener(new ActionListener() {
245
            @Override
246
            public void actionPerformed(ActionEvent e) {
247
                LOG.fine("show proxy options");
248
                OptionsDisplayer.getDefault().open("General"); // NOI18N
249
            }
250
        });
251
        fullClosingOptions = new Object[closingOptions.length + 2];
252
        System.arraycopy(closingOptions, 0, fullClosingOptions, 0, closingOptions.length);
253
        fullClosingOptions[fullClosingOptions.length - 2] = tryAgain;
254
        fullClosingOptions[fullClosingOptions.length - 1] = NotifyDescriptor.CANCEL_OPTION;
255
    }
256
257
    private Object showNoDownloadDialog(String cnb, String displayName) throws OperationException {
258
        DialogDescriptor networkProblem = new DialogDescriptor(
259
                problemPanel(nodownload_header(displayName), nodownload_message(displayName)), // message
260
                resolve_title(displayName), // title
261
                true, // modal
262
                null);
263
        initButtons();
264
        networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
265
        networkProblem.setAdditionalOptions(closingOptions);
266
        networkProblem.setClosingOptions(fullClosingOptions);
267
        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
268
        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
269
        networkProblemDialog.setVisible(true);
270
        Object answer = networkProblem.getValue();
271
        if (NotifyDescriptor.CANCEL_OPTION.equals(answer)
272
                || Arrays.asList(closingOptions).contains(answer)
273
                || answer.equals(NotifyDescriptor.DEFAULT_OPTION) /* escape */ ) {
274
            LOG.fine("cancel no download dialog");
275
            //throw new InterruptedException("user canceled download & install JUnit");
276
            return answer;
277
        } else if (tryAgain.equals(answer)) {
278
            LOG.fine("try again download()");
279
            return installPlugin(cnb, displayName);
280
        } else {
281
            assert false : "Unknown " + answer;
282
        }
283
        assert false : "Unknown " + answer;
284
        return NotifyDescriptor.DEFAULT_OPTION;
285
    }
286
287
    private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) {
288
        JPanel panel = new JPanel();
289
        progressLabel.setLabelFor(progressComponent);
290
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
291
        panel.setLayout(layout);
292
        layout.setHorizontalGroup(
293
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
294
            .addGroup(layout.createSequentialGroup()
295
                .addContainerGap()
296
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
297
                    .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
298
                    .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
299
                .addContainerGap())
300
        );
301
        layout.setVerticalGroup(
302
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
303
            .addGroup(layout.createSequentialGroup()
304
                .addGap(96, 96, 96)
305
                .addComponent(progressLabel)
306
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
307
                .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
308
                .addContainerGap(109, Short.MAX_VALUE))
309
        );
310
        return panel;
311
    }
312
313
    private static JPanel problemPanel(String header, String message) {
314
        JPanel panel = new JPanel();
315
        JLabel jLabel1 = new javax.swing.JLabel();
316
        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
317
        JTextArea jTextArea1 = new javax.swing.JTextArea();
318
319
        jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD));
320
        jLabel1.setText(header);
321
322
        jTextArea1.setColumns(20);
323
        jTextArea1.setEditable(false);
324
        jTextArea1.setLineWrap(true);
325
        jTextArea1.setWrapStyleWord(true);
326
        jTextArea1.setRows(5);
327
        jTextArea1.setText(message);
328
        jTextArea1.setOpaque(false);
329
        jScrollPane1.setViewportView(jTextArea1);
330
331
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
332
        panel.setLayout(layout);
333
        layout.setHorizontalGroup(
334
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
335
            .addGroup(layout.createSequentialGroup()
336
                .addContainerGap()
337
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
338
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
339
                    .addGroup(layout.createSequentialGroup()
340
                        .addComponent(jLabel1)
341
                        .addGap(107, 107, 107)))
342
                .addContainerGap())
343
        );
344
        layout.setVerticalGroup(
345
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
346
            .addGroup(layout.createSequentialGroup()
347
                .addContainerGap()
348
                .addComponent(jLabel1)
349
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
350
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
351
                .addGap(82, 82, 82))
352
        );
353
        return panel;
354
    }
355
356
}
357
(-)a/autoupdate.ui/src/org/netbeans/modules/autoupdate/ui/api/PluginManager.java (+47 lines)
Lines 43-55 Link Here
43
package org.netbeans.modules.autoupdate.ui.api;
43
package org.netbeans.modules.autoupdate.ui.api;
44
44
45
import java.util.List;
45
import java.util.List;
46
import java.util.logging.Level;
47
import java.util.logging.Logger;
48
import org.netbeans.api.annotations.common.CheckForNull;
49
import org.netbeans.api.annotations.common.NonNull;
46
import org.netbeans.api.autoupdate.InstallSupport;
50
import org.netbeans.api.autoupdate.InstallSupport;
47
import org.netbeans.api.autoupdate.OperationContainer;
51
import org.netbeans.api.autoupdate.OperationContainer;
48
import org.netbeans.api.autoupdate.OperationContainer.OperationInfo;
52
import org.netbeans.api.autoupdate.OperationContainer.OperationInfo;
53
import org.netbeans.api.autoupdate.OperationException;
49
import org.netbeans.api.autoupdate.UpdateManager;
54
import org.netbeans.api.autoupdate.UpdateManager;
55
import org.netbeans.api.autoupdate.UpdateUnit;
56
import org.netbeans.modules.autoupdate.ui.ModuleInstallerSupport;
50
import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizard;
57
import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizard;
51
import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizardModel;
58
import org.netbeans.modules.autoupdate.ui.wizards.InstallUnitWizardModel;
52
import org.netbeans.modules.autoupdate.ui.wizards.OperationWizardModel.OperationType;
59
import org.netbeans.modules.autoupdate.ui.wizards.OperationWizardModel.OperationType;
60
import org.openide.NotifyDescriptor;
61
import org.openide.util.Parameters;
53
62
54
/** Access to UI features of PluginManager that can be useful in other modules
63
/** Access to UI features of PluginManager that can be useful in other modules
55
 * as well. 
64
 * as well. 
Lines 67-72 Link Here
67
     * (until the user clicks through), so either call from AWT dispatch thread
76
     * (until the user clicks through), so either call from AWT dispatch thread
68
     * directly, or be sure you hold no locks and block no progress of other
77
     * directly, or be sure you hold no locks and block no progress of other
69
     * threads to avoid deadlocks.
78
     * threads to avoid deadlocks.
79
     * <p>
80
     * Single module installation can be handled easily by
81
     * {@link #installPlugin(java.lang.String, java.lang.String, java.lang.Object[])}.
70
<pre>
82
<pre>
71
{@link OperationContainer}<InstallSupport> container = OperationContainer.createForInstall();
83
{@link OperationContainer}<InstallSupport> container = OperationContainer.createForInstall();
72
for ({@link UpdateUnit} u : {@link UpdateManager#getUpdateUnits(org.netbeans.api.autoupdate.UpdateManager.TYPE[]) UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)}) {
84
for ({@link UpdateUnit} u : {@link UpdateManager#getUpdateUnits(org.netbeans.api.autoupdate.UpdateManager.TYPE[]) UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)}) {
Lines 83-88 Link Here
83
     * @param container the container with list of modules for install
95
     * @param container the container with list of modules for install
84
     * @return true if all the requested modules were successfullly installed, 
96
     * @return true if all the requested modules were successfullly installed, 
85
     *    false otherwise.
97
     *    false otherwise.
98
     * @see #installPlugin(java.lang.String, java.lang.String, java.lang.Object[]) 
86
     */
99
     */
87
    public static boolean openInstallWizard(OperationContainer<InstallSupport> container) {
100
    public static boolean openInstallWizard(OperationContainer<InstallSupport> container) {
88
        if (container == null) {
101
        if (container == null) {
Lines 100-103 Link Here
100
        OperationType doOperation = info.getUpdateUnit ().getInstalled () == null ? OperationType.INSTALL : OperationType.UPDATE;
113
        OperationType doOperation = info.getUpdateUnit ().getInstalled () == null ? OperationType.INSTALL : OperationType.UPDATE;
101
        return new InstallUnitWizard ().invokeWizard (new InstallUnitWizardModel (doOperation, container), false);
114
        return new InstallUnitWizard ().invokeWizard (new InstallUnitWizardModel (doOperation, container), false);
102
    }
115
    }
116
117
    /** Open standard dialog for installing a module including declared dependencies.
118
     * Shows it to the user, asks for confirmation, license acceptance, etc.
119
     * The whole operation requires AWT dispatch thread access (to show the dialog)
120
     * and blocks (until the user clicks through), so either call from AWT dispatch
121
     * thread directly, or be sure you hold no locks and block no progress of other
122
     * threads to avoid deadlocks.
123
     *
124
     * @param cnb the codenamebase of module to install
125
     * @param displayName the display name of the module
126
     * @param alternativeOptions alternative options possibly displayed in error
127
     *             dialog user may choose if it is not possible to install the plugin;
128
     *             if chosen the option is return value of this method
129
     * @return <code>null</code> if the module has been successfully installed
130
     *             and/or activated, otherwise it returns the options user has
131
     *             selected in problem dialog, typically {@link NotifyDescriptor#DEFAULT_OPTION}
132
     *             (on esc), {@link NotifyDescriptor#CANCEL_OPTION} or
133
     *             any of <code>alternativeOptions</code>.
134
     * @since 1.35
135
     */
136
    @CheckForNull
137
    public static Object installPlugin(@NonNull String cnb, @NonNull String displayName,
138
            @NonNull Object... alternativeOptions) {
139
        Parameters.notNull("cnb", cnb);
140
        Parameters.notNull("displayName", displayName);
141
        Parameters.notNull("alternativeOptions", alternativeOptions);
142
143
        try {
144
            return new ModuleInstallerSupport(alternativeOptions).installPlugin(cnb, displayName);
145
        } catch (OperationException ex) {
146
            Logger.getLogger(PluginManager.class.getName()).log(Level.WARNING, null, ex);
147
        }
148
        return NotifyDescriptor.DEFAULT_OPTION;
149
    }
103
}
150
}
(-)a/code.analysis/nbproject/project.xml (-9 / +1 lines)
Lines 33-51 Link Here
33
                    </run-dependency>
33
                    </run-dependency>
34
                </dependency>
34
                </dependency>
35
                <dependency>
35
                <dependency>
36
                    <code-name-base>org.netbeans.modules.autoupdate.services</code-name-base>
37
                    <build-prerequisite/>
38
                    <compile-dependency/>
39
                    <run-dependency>
40
                        <specification-version>1.29</specification-version>
41
                    </run-dependency>
42
                </dependency>
43
                <dependency>
44
                    <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
36
                    <code-name-base>org.netbeans.modules.autoupdate.ui</code-name-base>
45
                    <build-prerequisite/>
37
                    <build-prerequisite/>
46
                    <compile-dependency/>
38
                    <compile-dependency/>
47
                    <run-dependency>
39
                    <run-dependency>
48
                        <specification-version>1.26</specification-version>
40
                        <specification-version>1.35</specification-version>
49
                    </run-dependency>
41
                    </run-dependency>
50
                </dependency>
42
                </dependency>
51
                <dependency>
43
                <dependency>
(-)a/code.analysis/src/org/netbeans/modules/analysis/ModuleInstallerSupport.java (-330 lines)
Lines 1-330 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.analysis;
44
45
import java.awt.event.ActionEvent;
46
import org.netbeans.api.autoupdate.OperationSupport;
47
import org.netbeans.api.autoupdate.OperationSupport.Restarter;
48
import org.netbeans.api.options.OptionsDisplayer;
49
import javax.swing.JButton;
50
import javax.swing.JTextArea;
51
import javax.swing.JPanel;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
54
import java.awt.Dialog;
55
import java.awt.event.ActionListener;
56
import javax.swing.JComponent;
57
import javax.swing.JLabel;
58
import org.openide.DialogDisplayer;
59
import java.io.IOException;
60
import java.util.List;
61
import javax.swing.JScrollPane;
62
import org.netbeans.api.autoupdate.InstallSupport;
63
import org.netbeans.api.autoupdate.OperationContainer;
64
import org.netbeans.api.autoupdate.UpdateElement;
65
import org.netbeans.api.autoupdate.UpdateManager;
66
import org.netbeans.api.autoupdate.UpdateUnit;
67
import org.netbeans.api.autoupdate.UpdateUnitProvider;
68
import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
69
import org.netbeans.api.progress.ProgressHandle;
70
import org.netbeans.api.progress.ProgressHandleFactory;
71
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
72
import org.openide.DialogDescriptor;
73
import org.openide.NotifyDescriptor;
74
import org.openide.awt.Mnemonics;
75
import org.openide.util.NbBundle.Messages;
76
import org.openide.util.RequestProcessor;
77
import static org.netbeans.modules.analysis.Bundle.*;
78
79
/**
80
 * Copied and adjusted from the JUnitLibraryDownloader
81
 */
82
public class ModuleInstallerSupport  {
83
    private static RequestProcessor RP = new RequestProcessor(ModuleInstallerSupport.class.getName(), 1);
84
    private static final Logger LOG = Logger.getLogger(ModuleInstallerSupport.class.getName());
85
86
    @Messages({
87
        "searching_handle=Searching for \"{0}\" library on NetBeans plugin portal...",
88
        "resolve_title=Resolve \"{0}\" Reference Problem",
89
        "networkproblem_header=Unable to connect  to the NetBeans plugin portal",
90
        "networkproblem_message=Check your proxy settings or try again later. "
91
            + "The server may be unavailable at the moment. "
92
            + "You may also want to make sure that your firewall is not blocking network traffic.",
93
        "proxy_button=&Proxy Settings...",
94
        "tryagain_button=Try &Again",
95
        "nodownload_header=\"{0}\" module has not been downloaded",
96
        "nodownload_message=You can try to download \"{0}\" module again",
97
        "active_handle=Activating {0}"
98
    })
99
    
100
    private JButton tryAgain;
101
    private JButton proxySettings;
102
103
    @SuppressWarnings("SleepWhileInLoop")
104
    public boolean download(String cnb, final String displayName) throws Exception {
105
        UpdateUnit unit = findModule(cnb);
106
        if (unit == null) {
107
            final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle(displayName));
108
            initButtons();
109
            final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)),
110
                    ProgressHandleFactory.createProgressComponent(handle)), resolve_title(displayName), true, null);
111
            handle.setInitialDelay (0);
112
            handle.start ();
113
            searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION});
114
            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
115
            final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching);
116
            RP.post(new Runnable() {
117
118
                @Override
119
                public void run() {
120
                    // May be first start, when no update lists have yet been downloaded.
121
                    try {
122
                        for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
123
                            p.refresh(handle, true);
124
                        }
125
                        // close searching
126
                        dlg.dispose();
127
                    } catch (IOException ex) {
128
                        LOG.log(Level.FINE, ex.getMessage(), ex);
129
                        if (! dlg.isVisible()) {
130
                            LOG.fine("dialog not visible => do nothing");
131
                            return ;
132
                        }
133
                        DialogDescriptor networkProblem = new DialogDescriptor(
134
                                problemPanel(resolve_title(displayName), networkproblem_message()), // message
135
                                networkproblem_header(), // title
136
                                true, // modal
137
                                null);
138
                        networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION});
139
                        networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
140
                        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
141
                        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
142
                        networkProblemDialog.setVisible(true);
143
                        Object answer = networkProblem.getValue();
144
                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) {
145
                            LOG.fine("cancel network problem dialog");
146
                            searching.setValue(answer);
147
                            dlg.dispose();
148
                        } else if (tryAgain.equals(answer)) {
149
                            LOG.fine("try again searching");
150
                            RP.post(this);
151
                            assert false : "Unknown " + answer;
152
                        }
153
                    }
154
                }
155
            });
156
            dlg.setVisible(true);
157
            handle.finish();
158
            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) || searching.getValue().equals(-1) /* escape */) {
159
                LOG.log(Level.FINE, "user canceled searching for {0}", cnb);
160
                return showNoDownloadDialog(cnb, displayName);
161
            }
162
            unit = findModule(cnb);
163
            if (unit == null) {
164
                LOG.log(Level.FINE, "could not find {0} on any update site", cnb);
165
                return showNoDownloadDialog(cnb, displayName);
166
            }
167
        }
168
        // check if module installed
169
        if (unit.getInstalled() != null) {
170
            LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled());
171
            if (unit.getInstalled().isEnabled()) {
172
                throw new Exception(unit.getInstalled() + " already installed and active");
173
            } else {
174
                // activate it
175
                OperationContainer<OperationSupport> oc = OperationContainer.createForEnable();
176
                if (!oc.canBeAdded(unit, unit.getInstalled())) {
177
                    throw new Exception("could not add " + unit.getInstalled() + " for activation");
178
                }
179
                for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) {
180
                    oc.add(req);
181
                }
182
                ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle(displayName));
183
                Restarter restarter = oc.getSupport().doOperation(activeHandle);
184
                assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active";
185
                // XXX new library & build.properties apparently do not show up immediately... how to listen properly?
186
                return true;
187
            }
188
        }
189
        List<UpdateElement> updates = unit.getAvailableUpdates();
190
        if (updates.isEmpty()) {
191
            throw new Exception("no updates for " + unit);
192
        }
193
        OperationContainer<InstallSupport> oc = OperationContainer.createForInstall();
194
        UpdateElement element = updates.get(0);
195
        if (!oc.canBeAdded(unit, element)) {
196
            throw new Exception("could not add " + element + " to updates");
197
        }
198
        for (UpdateElement req : oc.add(element).getRequiredElements()) {
199
            oc.add(req);
200
        }
201
        if (!PluginManager.openInstallWizard(oc)) {
202
            LOG.fine("user canceled PM");
203
            return showNoDownloadDialog(cnb, displayName);
204
        }
205
        return true;
206
    }
207
208
    private UpdateUnit findModule(String cnb) throws IOException {
209
        for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
210
            if (unit.getCodeName().equals(cnb)) {
211
                return unit;
212
            }
213
        }
214
        return null;
215
    }
216
    
217
    private void initButtons() {
218
        if (tryAgain != null) {
219
            return ;
220
        }
221
        tryAgain = new JButton();
222
        proxySettings = new JButton();
223
        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
224
        Mnemonics.setLocalizedText(proxySettings, proxy_button());
225
        proxySettings.addActionListener(new ActionListener() {
226
            @Override
227
            public void actionPerformed(ActionEvent e) {
228
                LOG.fine("show proxy options");
229
                OptionsDisplayer.getDefault().open("General"); // NOI18N
230
            }
231
        });
232
    }
233
    
234
    private boolean showNoDownloadDialog(String cnb, String displayName) throws Exception {
235
        DialogDescriptor networkProblem = new DialogDescriptor(
236
                problemPanel(nodownload_header(displayName), nodownload_message(displayName)), // message
237
                resolve_title(displayName), // title
238
                true, // modal
239
                null);
240
        initButtons();
241
        networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
242
        networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
243
        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
244
        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
245
        networkProblemDialog.setVisible(true);
246
        Object answer = networkProblem.getValue();
247
        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) {
248
            LOG.fine("cancel no download dialog");
249
            //throw new InterruptedException("user canceled download & install JUnit");
250
            return false;
251
        } else if (tryAgain.equals(answer)) {
252
            LOG.fine("try again download()");
253
            return download(cnb, displayName);
254
        } else {
255
            assert false : "Unknown " + answer;
256
        }
257
        assert false : "Unknown " + answer;
258
        return false;
259
    }
260
    
261
    private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) {
262
        JPanel panel = new JPanel();
263
        progressLabel.setLabelFor(progressComponent);
264
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
265
        panel.setLayout(layout);
266
        layout.setHorizontalGroup(
267
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
268
            .addGroup(layout.createSequentialGroup()
269
                .addContainerGap()
270
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
271
                    .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
272
                    .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
273
                .addContainerGap())
274
        );
275
        layout.setVerticalGroup(
276
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
277
            .addGroup(layout.createSequentialGroup()
278
                .addGap(96, 96, 96)
279
                .addComponent(progressLabel)
280
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
281
                .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
282
                .addContainerGap(109, Short.MAX_VALUE))
283
        );
284
        return panel;
285
    }
286
    
287
    private static JPanel problemPanel(String header, String message) {
288
        JPanel panel = new JPanel();
289
        JLabel jLabel1 = new javax.swing.JLabel();
290
        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
291
        JTextArea jTextArea1 = new javax.swing.JTextArea();
292
293
        jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD));
294
        jLabel1.setText(header);
295
296
        jTextArea1.setColumns(20);
297
        jTextArea1.setEditable(false);
298
        jTextArea1.setLineWrap(true);
299
        jTextArea1.setWrapStyleWord(true);
300
        jTextArea1.setRows(5);
301
        jTextArea1.setText(message);
302
        jTextArea1.setOpaque(false);
303
        jScrollPane1.setViewportView(jTextArea1);
304
305
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
306
        panel.setLayout(layout);
307
        layout.setHorizontalGroup(
308
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
309
            .addGroup(layout.createSequentialGroup()
310
                .addContainerGap()
311
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
312
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
313
                    .addGroup(layout.createSequentialGroup()
314
                        .addComponent(jLabel1)
315
                        .addGap(107, 107, 107)))
316
                .addContainerGap())
317
        );
318
        layout.setVerticalGroup(
319
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
320
            .addGroup(layout.createSequentialGroup()
321
                .addContainerGap()
322
                .addComponent(jLabel1)
323
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
324
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
325
                .addGap(82, 82, 82))
326
        );
327
        return panel;
328
    }
329
330
}
(-)a/code.analysis/src/org/netbeans/modules/analysis/Utils.java (-6 / +2 lines)
Lines 45-51 Link Here
45
import java.util.HashSet;
45
import java.util.HashSet;
46
import java.util.Set;
46
import java.util.Set;
47
import org.netbeans.modules.analysis.spi.Analyzer.MissingPlugin;
47
import org.netbeans.modules.analysis.spi.Analyzer.MissingPlugin;
48
import org.openide.util.Exceptions;
48
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
49
49
50
/**
50
/**
51
 *
51
 *
Lines 57-67 Link Here
57
        Set<MissingPlugin> plugins = new HashSet<MissingPlugin>(inPlugins);
57
        Set<MissingPlugin> plugins = new HashSet<MissingPlugin>(inPlugins);
58
58
59
        for (MissingPlugin missing : plugins) {
59
        for (MissingPlugin missing : plugins) {
60
            try {
60
            PluginManager.installPlugin(SPIAccessor.ACCESSOR.getCNB(missing), SPIAccessor.ACCESSOR.getDisplayName(missing));
61
                new ModuleInstallerSupport().download(SPIAccessor.ACCESSOR.getCNB(missing), SPIAccessor.ACCESSOR.getDisplayName(missing));
62
            } catch (Exception ex) {
63
                Exceptions.printStackTrace(ex);
64
            }
65
        }
61
        }
66
    }
62
    }
67
}
63
}
(-)a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/FindBugsPanel.java (-5 / +2 lines)
Lines 41-46 Link Here
41
 */
41
 */
42
package org.netbeans.modules.findbugs.installer;
42
package org.netbeans.modules.findbugs.installer;
43
43
44
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
44
import org.openide.util.Exceptions;
45
import org.openide.util.Exceptions;
45
import org.openide.util.NbBundle.Messages;
46
import org.openide.util.NbBundle.Messages;
46
47
Lines 95-105 Link Here
95
96
96
    @Messages("FindBugs_Library=FindBugs Library")
97
    @Messages("FindBugs_Library=FindBugs Library")
97
    private void installActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_installActionPerformed
98
    private void installActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_installActionPerformed
98
        try {
99
        PluginManager.installPlugin("org.netbeans.modules.findbugs", Bundle.FindBugs_Library());
99
            new ModuleInstallerSupport().download("org.netbeans.modules.findbugs", Bundle.FindBugs_Library());
100
        } catch (Exception ex) {
101
            Exceptions.printStackTrace(ex);
102
        }
103
    }//GEN-LAST:event_installActionPerformed
100
    }//GEN-LAST:event_installActionPerformed
104
101
105
    void load() {
102
    void load() {
(-)a/findbugs.installer/src/org/netbeans/modules/findbugs/installer/ModuleInstallerSupport.java (-331 lines)
Lines 1-331 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
42
43
package org.netbeans.modules.findbugs.installer;
44
45
import java.awt.event.ActionEvent;
46
import org.netbeans.api.autoupdate.OperationSupport;
47
import org.netbeans.api.autoupdate.OperationSupport.Restarter;
48
import org.netbeans.api.options.OptionsDisplayer;
49
import javax.swing.JButton;
50
import javax.swing.JTextArea;
51
import javax.swing.JPanel;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
54
import java.awt.Dialog;
55
import java.awt.event.ActionListener;
56
import javax.swing.JComponent;
57
import javax.swing.JLabel;
58
import org.openide.DialogDisplayer;
59
import java.io.IOException;
60
import java.util.List;
61
import javax.swing.JScrollPane;
62
import org.netbeans.api.autoupdate.InstallSupport;
63
import org.netbeans.api.autoupdate.OperationContainer;
64
import org.netbeans.api.autoupdate.UpdateElement;
65
import org.netbeans.api.autoupdate.UpdateManager;
66
import org.netbeans.api.autoupdate.UpdateUnit;
67
import org.netbeans.api.autoupdate.UpdateUnitProvider;
68
import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
69
import org.netbeans.api.progress.ProgressHandle;
70
import org.netbeans.api.progress.ProgressHandleFactory;
71
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
72
import org.openide.DialogDescriptor;
73
import org.openide.NotifyDescriptor;
74
import org.openide.awt.Mnemonics;
75
import org.openide.util.NbBundle.Messages;
76
import org.openide.util.RequestProcessor;
77
import static org.netbeans.modules.findbugs.installer.Bundle.*;
78
79
/**
80
 * Copied and adjusted from the JUnitLibraryDownloader
81
 */
82
public class ModuleInstallerSupport  {
83
    private static RequestProcessor RP = new RequestProcessor(ModuleInstallerSupport.class.getName(), 1);
84
    private static final Logger LOG = Logger.getLogger(ModuleInstallerSupport.class.getName());
85
86
    @Messages({
87
        "searching_handle=Searching for \"{0}\" library on NetBeans plugin portal...",
88
        "resolve_title=Resolve \"{0}\" Reference Problem",
89
        "networkproblem_header=Unable to connect  to the NetBeans plugin portal",
90
        "networkproblem_message=Check your proxy settings or try again later. "
91
            + "The server may be unavailable at the moment. "
92
            + "You may also want to make sure that your firewall is not blocking network traffic.",
93
        "proxy_button=&Proxy Settings...",
94
        "tryagain_button=Try &Again",
95
        "nodownload_header=\"{0}\" module has not been downloaded",
96
        "nodownload_message=You can try to download \"{0}\" module again",
97
        "active_handle=Activating {0}"
98
    })
99
    
100
    private JButton tryAgain;
101
    private JButton proxySettings;
102
103
    @SuppressWarnings("SleepWhileInLoop")
104
    public boolean download(String cnb, final String displayName) throws Exception {
105
        UpdateUnit unit = findModule(cnb);
106
        if (unit == null) {
107
            final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle(displayName));
108
            initButtons();
109
            final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle(displayName)),
110
                    ProgressHandleFactory.createProgressComponent(handle)), resolve_title(displayName), true, null);
111
            handle.setInitialDelay (0);
112
            handle.start ();
113
            searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION});
114
            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
115
            final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching);
116
            RP.post(new Runnable() {
117
118
                @Override
119
                public void run() {
120
                    // May be first start, when no update lists have yet been downloaded.
121
                    try {
122
                        for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
123
                            p.refresh(handle, true);
124
                        }
125
                        // close searching
126
                        dlg.dispose();
127
                    } catch (IOException ex) {
128
                        LOG.log(Level.FINE, ex.getMessage(), ex);
129
                        if (! dlg.isVisible()) {
130
                            LOG.fine("dialog not visible => do nothing");
131
                            return ;
132
                        }
133
                        DialogDescriptor networkProblem = new DialogDescriptor(
134
                                problemPanel(resolve_title(displayName), networkproblem_message()), // message
135
                                networkproblem_header(), // title
136
                                true, // modal
137
                                null);
138
                        networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION});
139
                        networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
140
                        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
141
                        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
142
                        networkProblemDialog.setVisible(true);
143
                        Object answer = networkProblem.getValue();
144
                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) {
145
                            LOG.fine("cancel network problem dialog");
146
                            searching.setValue(answer);
147
                            dlg.dispose();
148
                        } else if (tryAgain.equals(answer)) {
149
                            LOG.fine("try again searching");
150
                            RP.post(this);
151
                        } else {
152
                            assert false : "Unknown " + answer;
153
                        }
154
                    }
155
                }
156
            });
157
            dlg.setVisible(true);
158
            handle.finish();
159
            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) || searching.getValue().equals(-1) /* escape */) {
160
                LOG.log(Level.FINE, "user canceled searching for {0}", cnb);
161
                return showNoDownloadDialog(cnb, displayName);
162
            }
163
            unit = findModule(cnb);
164
            if (unit == null) {
165
                LOG.log(Level.FINE, "could not find {0} on any update site", cnb);
166
                return showNoDownloadDialog(cnb, displayName);
167
            }
168
        }
169
        // check if module installed
170
        if (unit.getInstalled() != null) {
171
            LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled());
172
            if (unit.getInstalled().isEnabled()) {
173
                throw new Exception(unit.getInstalled() + " already installed and active");
174
            } else {
175
                // activate it
176
                OperationContainer<OperationSupport> oc = OperationContainer.createForEnable();
177
                if (!oc.canBeAdded(unit, unit.getInstalled())) {
178
                    throw new Exception("could not add " + unit.getInstalled() + " for activation");
179
                }
180
                for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) {
181
                    oc.add(req);
182
                }
183
                ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle(displayName));
184
                Restarter restarter = oc.getSupport().doOperation(activeHandle);
185
                assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active";
186
                // XXX new library & build.properties apparently do not show up immediately... how to listen properly?
187
                return true;
188
            }
189
        }
190
        List<UpdateElement> updates = unit.getAvailableUpdates();
191
        if (updates.isEmpty()) {
192
            throw new Exception("no updates for " + unit);
193
        }
194
        OperationContainer<InstallSupport> oc = OperationContainer.createForInstall();
195
        UpdateElement element = updates.get(0);
196
        if (!oc.canBeAdded(unit, element)) {
197
            throw new Exception("could not add " + element + " to updates");
198
        }
199
        for (UpdateElement req : oc.add(element).getRequiredElements()) {
200
            oc.add(req);
201
        }
202
        if (!PluginManager.openInstallWizard(oc)) {
203
            LOG.fine("user canceled PM");
204
            return showNoDownloadDialog(cnb, displayName);
205
        }
206
        return true;
207
    }
208
209
    private UpdateUnit findModule(String cnb) throws IOException {
210
        for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
211
            if (unit.getCodeName().equals(cnb)) {
212
                return unit;
213
            }
214
        }
215
        return null;
216
    }
217
    
218
    private void initButtons() {
219
        if (tryAgain != null) {
220
            return ;
221
        }
222
        tryAgain = new JButton();
223
        proxySettings = new JButton();
224
        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
225
        Mnemonics.setLocalizedText(proxySettings, proxy_button());
226
        proxySettings.addActionListener(new ActionListener() {
227
            @Override
228
            public void actionPerformed(ActionEvent e) {
229
                LOG.fine("show proxy options");
230
                OptionsDisplayer.getDefault().open("General"); // NOI18N
231
            }
232
        });
233
    }
234
    
235
    private boolean showNoDownloadDialog(String cnb, String displayName) throws Exception {
236
        DialogDescriptor networkProblem = new DialogDescriptor(
237
                problemPanel(nodownload_header(displayName), nodownload_message(displayName)), // message
238
                resolve_title(displayName), // title
239
                true, // modal
240
                null);
241
        initButtons();
242
        networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
243
        networkProblem.setClosingOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
244
        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
245
        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
246
        networkProblemDialog.setVisible(true);
247
        Object answer = networkProblem.getValue();
248
        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) {
249
            LOG.fine("cancel no download dialog");
250
            //throw new InterruptedException("user canceled download & install JUnit");
251
            return false;
252
        } else if (tryAgain.equals(answer)) {
253
            LOG.fine("try again download()");
254
            return download(cnb, displayName);
255
        } else {
256
            assert false : "Unknown " + answer;
257
        }
258
        assert false : "Unknown " + answer;
259
        return false;
260
    }
261
    
262
    private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) {
263
        JPanel panel = new JPanel();
264
        progressLabel.setLabelFor(progressComponent);
265
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
266
        panel.setLayout(layout);
267
        layout.setHorizontalGroup(
268
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
269
            .addGroup(layout.createSequentialGroup()
270
                .addContainerGap()
271
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
272
                    .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
273
                    .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
274
                .addContainerGap())
275
        );
276
        layout.setVerticalGroup(
277
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
278
            .addGroup(layout.createSequentialGroup()
279
                .addGap(96, 96, 96)
280
                .addComponent(progressLabel)
281
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
282
                .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
283
                .addContainerGap(109, Short.MAX_VALUE))
284
        );
285
        return panel;
286
    }
287
    
288
    private static JPanel problemPanel(String header, String message) {
289
        JPanel panel = new JPanel();
290
        JLabel jLabel1 = new javax.swing.JLabel();
291
        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
292
        JTextArea jTextArea1 = new javax.swing.JTextArea();
293
294
        jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD));
295
        jLabel1.setText(header);
296
297
        jTextArea1.setColumns(20);
298
        jTextArea1.setEditable(false);
299
        jTextArea1.setLineWrap(true);
300
        jTextArea1.setWrapStyleWord(true);
301
        jTextArea1.setRows(5);
302
        jTextArea1.setText(message);
303
        jTextArea1.setOpaque(false);
304
        jScrollPane1.setViewportView(jTextArea1);
305
306
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
307
        panel.setLayout(layout);
308
        layout.setHorizontalGroup(
309
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
310
            .addGroup(layout.createSequentialGroup()
311
                .addContainerGap()
312
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
313
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
314
                    .addGroup(layout.createSequentialGroup()
315
                        .addComponent(jLabel1)
316
                        .addGap(107, 107, 107)))
317
                .addContainerGap())
318
        );
319
        layout.setVerticalGroup(
320
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
321
            .addGroup(layout.createSequentialGroup()
322
                .addContainerGap()
323
                .addComponent(jLabel1)
324
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
325
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
326
                .addGap(82, 82, 82))
327
        );
328
        return panel;
329
    }
330
331
}
(-)a/junit/src/org/netbeans/modules/junit/JUnitLibraryDownloader.java (-301 / +12 lines)
Lines 42-83 Link Here
42
42
43
package org.netbeans.modules.junit;
43
package org.netbeans.modules.junit;
44
44
45
import java.awt.event.ActionEvent;
46
import org.netbeans.api.autoupdate.OperationSupport;
47
import org.netbeans.api.autoupdate.OperationSupport.Restarter;
48
import org.netbeans.api.options.OptionsDisplayer;
49
import javax.swing.JButton;
45
import javax.swing.JButton;
50
import javax.swing.JTextArea;
51
import javax.swing.JPanel;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
46
import java.util.logging.Logger;
54
import java.awt.Dialog;
55
import java.awt.event.ActionListener;
56
import javax.swing.JComponent;
57
import javax.swing.JLabel;
58
import org.openide.DialogDisplayer;
59
import java.io.IOException;
60
import java.util.List;
61
import java.util.concurrent.Callable;
47
import java.util.concurrent.Callable;
62
import javax.swing.JScrollPane;
63
import org.netbeans.api.autoupdate.InstallSupport;
64
import org.netbeans.api.autoupdate.OperationContainer;
65
import org.netbeans.api.autoupdate.UpdateElement;
66
import org.netbeans.api.autoupdate.UpdateManager;
67
import org.netbeans.api.autoupdate.UpdateUnit;
68
import org.netbeans.api.autoupdate.UpdateUnitProvider;
69
import org.netbeans.api.autoupdate.UpdateUnitProviderFactory;
70
import org.netbeans.api.progress.ProgressHandle;
71
import org.netbeans.api.progress.ProgressHandleFactory;
72
import org.netbeans.api.project.libraries.Library;
48
import org.netbeans.api.project.libraries.Library;
73
import org.netbeans.api.project.libraries.LibraryManager;
49
import org.netbeans.api.project.libraries.LibraryManager;
74
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
50
import org.netbeans.modules.autoupdate.ui.api.PluginManager;
75
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport.LibraryDefiner;
51
import org.netbeans.spi.java.project.support.ui.BrokenReferencesSupport.LibraryDefiner;
76
import org.openide.DialogDescriptor;
77
import org.openide.NotifyDescriptor;
78
import org.openide.awt.Mnemonics;
52
import org.openide.awt.Mnemonics;
79
import org.openide.util.NbBundle.Messages;
53
import org.openide.util.NbBundle.Messages;
80
import org.openide.util.RequestProcessor;
81
import org.openide.util.lookup.ServiceProvider;
54
import org.openide.util.lookup.ServiceProvider;
82
import static org.netbeans.modules.junit.Bundle.*;
55
import static org.netbeans.modules.junit.Bundle.*;
83
56
Lines 85-111 Link Here
85
 * Defines JUnit 3.x/4.x libraries by downloading their defining modules.
58
 * Defines JUnit 3.x/4.x libraries by downloading their defining modules.
86
 */
59
 */
87
@ServiceProvider(service=LibraryDefiner.class)
60
@ServiceProvider(service=LibraryDefiner.class)
88
public class JUnitLibraryDownloader implements LibraryDefiner {
61
public class JUnitLibraryDefiner implements LibraryDefiner {
89
    private static RequestProcessor RP = new RequestProcessor(JUnitLibraryDownloader.class.getName(), 1);
90
    private static final Logger LOG = Logger.getLogger(JUnitLibraryDownloader.class.getName());
91
62
92
    @Messages({
63
    @Messages({
93
        "searching_handle=Searching for \"junit\" library on NetBeans plugin portal...",
94
        "resolve_title=Resolve \"junit\" Reference Problem",
95
        "networkproblem_header=Unable to connect  to the NetBeans plugin portal",
96
        "networkproblem_message=Check your proxy settings or try again later. "
97
            + "The server may be unavailable at the moment. "
98
            + "You may also want to make sure that your firewall is not blocking network traffic. \n\n"
99
            + "If you have the missing \"junit\" library, you can resolve the reference "
100
            + "problem manually using Library Manager.",
101
        "proxy_button=&Proxy Settings...",
102
        "library_button=&Library Manager...",
64
        "library_button=&Library Manager...",
103
        "tryagain_button=Try &Again",
65
        "library_name=junit"
104
        "nodownload_header=\"junit\" library has not been downloaded",
105
        "nodownload_message=You can try to download \"junit\" library again, or \n\n"
106
            + "if you have the missing \"junit\" library, you can resolve the reference "
107
            + "problem manually using Library Manager.",
108
        "active_handle=Activating JUnit"
109
    })
66
    })
110
    
67
    
111
    public @Override Callable<Library> missingLibrary(final String name) {
68
    public @Override Callable<Library> missingLibrary(final String name) {
Lines 113-384 Link Here
113
            return null;
70
            return null;
114
        }
71
        }
115
        return new Callable<Library>() {
72
        return new Callable<Library>() {
73
74
            @SuppressWarnings("SleepWhileInLoop")
116
            public @Override Library call() throws Exception {
75
            public @Override Library call() throws Exception {
117
                return download(name);
76
                JButton libraryManager = new JButton();
118
            }
77
                Mnemonics.setLocalizedText(libraryManager, library_button());
119
        };
78
                Object ret = PluginManager.installPlugin("org.netbeans.modules.junitlib", library_name(), libraryManager);
120
    }
79
                if (libraryManager.equals(ret)) {
121
    
80
                    throw new Exception("junitlib failed/canceled to install properly, open library manager instaed");
122
    private JButton libraryManager;
123
    private JButton tryAgain;
124
    private JButton proxySettings;
125
126
    @SuppressWarnings("SleepWhileInLoop")
127
    private Library download(String name) throws Exception {
128
        UpdateUnit unit = findJUnitLib();
129
        if (unit == null) {
130
            final ProgressHandle handle = ProgressHandleFactory.createHandle(searching_handle());
131
            initButtons();
132
            final DialogDescriptor searching = new DialogDescriptor(searchingPanel(new JLabel(searching_handle()),
133
                    ProgressHandleFactory.createProgressComponent(handle)), resolve_title(), true, null);
134
            handle.setInitialDelay (0);
135
            handle.start ();
136
            searching.setOptions(new Object[] {NotifyDescriptor.CANCEL_OPTION});
137
            searching.setMessageType(NotifyDescriptor.PLAIN_MESSAGE);
138
            final Dialog dlg = DialogDisplayer.getDefault().createDialog(searching);
139
            RP.post(new Runnable() {
140
141
                @Override
142
                public void run() {
143
                    // May be first start, when no update lists have yet been downloaded.
144
                    try {
145
                        for (UpdateUnitProvider p : UpdateUnitProviderFactory.getDefault().getUpdateUnitProviders(true)) {
146
                            p.refresh(handle, true);
147
                        }
148
                        // close searching
149
                        dlg.dispose();
150
                    } catch (IOException ex) {
151
                        Logger.getLogger(JUnitLibraryDownloader.class.getName()).log(Level.FINE, ex.getMessage(), ex);
152
                        if (! dlg.isVisible()) {
153
                            LOG.fine("dialog not visible => do nothing");
154
                            return ;
155
                        }
156
                        DialogDescriptor networkProblem = new DialogDescriptor(
157
                                problemPanel(resolve_title(), networkproblem_message()), // message
158
                                networkproblem_header(), // title
159
                                true, // modal
160
                                null);
161
                        networkProblem.setOptions(new Object[] {tryAgain, proxySettings, NotifyDescriptor.CANCEL_OPTION});
162
                        networkProblem.setAdditionalOptions(new Object[] {libraryManager});
163
                        networkProblem.setClosingOptions(new Object[] {libraryManager, tryAgain, NotifyDescriptor.CANCEL_OPTION});
164
                        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
165
                        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
166
                        networkProblemDialog.setVisible(true);
167
                        Object answer = networkProblem.getValue();
168
                        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) {
169
                            LOG.fine("cancel network problem dialog");
170
                            searching.setValue(answer);
171
                            dlg.dispose();
172
                        } else if (tryAgain.equals(answer)) {
173
                            LOG.fine("try again searching");
174
                            RP.post(this);
175
                        } else if (libraryManager.equals(answer)) {
176
                            LOG.fine("open library manager");
177
                            searching.setValue(answer);
178
                            dlg.dispose();
179
                        } else {
180
                            assert false : "Unknown " + answer;
181
                        }
182
                    }
183
                }
81
                }
184
            });
185
            dlg.setVisible(true);
186
            handle.finish();
187
            if (NotifyDescriptor.CANCEL_OPTION.equals(searching.getValue()) || searching.getValue().equals(-1) /* escape */) {
188
                LOG.fine("user canceled searching JUnit");
189
                return showNoDownloadDialog(name);
190
            } else if (libraryManager.equals(searching.getValue())) {
191
                throw new Exception("user canceled searching");
192
            }
193
            unit = findJUnitLib();
194
            if (unit == null) {
195
                LOG.fine("could not find junitlib on any update site");
196
                return showNoDownloadDialog(name);
197
            }
198
        }
199
        // check if JUnit installed
200
        if (unit.getInstalled() != null) {
201
            LOG.fine(unit.getInstalled() + " already installed. Is active? " + unit.getInstalled().isEnabled());
202
            if (unit.getInstalled().isEnabled()) {
203
                throw new Exception(unit.getInstalled() + " already installed and active");
204
            } else {
205
                // activate it
206
                OperationContainer<OperationSupport> oc = OperationContainer.createForEnable();
207
                if (!oc.canBeAdded(unit, unit.getInstalled())) {
208
                    throw new Exception("could not add " + unit.getInstalled() + " for activation");
209
                }
210
                for (UpdateElement req : oc.add(unit.getInstalled()).getRequiredElements()) {
211
                    oc.add(req);
212
                }
213
                ProgressHandle activeHandle = ProgressHandleFactory.createHandle (active_handle());
214
                Restarter restarter = oc.getSupport().doOperation(activeHandle);
215
                assert restarter == null : "No Restater need to make " + unit.getInstalled() + " active";
216
                // XXX new library & build.properties apparently do not show up immediately... how to listen properly?
82
                // XXX new library & build.properties apparently do not show up immediately... how to listen properly?
217
                for (int i = 0; i < 10; i++) {
83
                for (int i = 0; i < 20; i++) {
218
                    Library lib = LibraryManager.getDefault().getLibrary(name);
84
                    Library lib = LibraryManager.getDefault().getLibrary(name);
219
                    if (lib != null) {
85
                    if (lib != null) {
220
                        return lib;
86
                        return lib;
221
                    }
87
                    }
222
                    Thread.sleep(1000);
88
                    Thread.sleep(1000);
223
                }
89
                }
224
                LOG.info("junitlib failed to make active properly");
90
                return null;
225
                return showNoDownloadDialog(name);
226
            }
91
            }
227
        }
92
        };
228
        List<UpdateElement> updates = unit.getAvailableUpdates();
229
        if (updates.isEmpty()) {
230
            throw new Exception("no updates for " + unit);
231
        }
232
        OperationContainer<InstallSupport> oc = OperationContainer.createForInstall();
233
        UpdateElement element = updates.get(0);
234
        if (!oc.canBeAdded(unit, element)) {
235
            throw new Exception("could not add " + element + " to updates");
236
        }
237
        for (UpdateElement req : oc.add(element).getRequiredElements()) {
238
            oc.add(req);
239
        }
240
        if (!PluginManager.openInstallWizard(oc)) {
241
            LOG.fine("user canceled PM");
242
            return showNoDownloadDialog(name);
243
        }
244
        // XXX new library & build.properties apparently do not show up immediately... how to listen properly?
245
        for (int i = 0; i < 20; i++) {
246
            Library lib = LibraryManager.getDefault().getLibrary(name);
247
            if (lib != null) {
248
                return lib;
249
            }
250
            Thread.sleep(1000);
251
        }
252
        LOG.info("junitlib failed to install properly");
253
        return showNoDownloadDialog(name);
254
    }
255
256
    private UpdateUnit findJUnitLib() throws IOException {
257
        for (UpdateUnit unit : UpdateManager.getDefault().getUpdateUnits(UpdateManager.TYPE.MODULE)) {
258
            if (unit.getCodeName().equals("org.netbeans.modules.junitlib")) {
259
                return unit;
260
            }
261
        }
262
        return null;
263
    }
264
    
265
    private void initButtons() {
266
        if (libraryManager != null) {
267
            return ;
268
        }
269
        libraryManager = new JButton();
270
        tryAgain = new JButton();
271
        proxySettings = new JButton();
272
        Mnemonics.setLocalizedText(tryAgain, tryagain_button());
273
        Mnemonics.setLocalizedText(libraryManager, library_button());
274
        Mnemonics.setLocalizedText(proxySettings, proxy_button());
275
        proxySettings.addActionListener(new ActionListener() {
276
            @Override
277
            public void actionPerformed(ActionEvent e) {
278
                LOG.fine("show proxy options");
279
                OptionsDisplayer.getDefault().open("General"); // NOI18N
280
            }
281
        });
282
    }
283
    
284
    private Library showNoDownloadDialog(String name) throws Exception {
285
        DialogDescriptor networkProblem = new DialogDescriptor(
286
                problemPanel(nodownload_header(), nodownload_message()), // message
287
                resolve_title(), // title
288
                true, // modal
289
                null);
290
        initButtons();
291
        networkProblem.setOptions(new Object[] {tryAgain, NotifyDescriptor.CANCEL_OPTION});
292
        networkProblem.setAdditionalOptions(new Object[] {libraryManager});
293
        networkProblem.setClosingOptions(new Object[] {libraryManager, tryAgain, NotifyDescriptor.CANCEL_OPTION});
294
        networkProblem.setMessageType(NotifyDescriptor.WARNING_MESSAGE);
295
        Dialog networkProblemDialog = DialogDisplayer.getDefault().createDialog(networkProblem);
296
        networkProblemDialog.setVisible(true);
297
        Object answer = networkProblem.getValue();
298
        if (NotifyDescriptor.CANCEL_OPTION.equals(answer) || answer.equals(-1) /* escape */ ) {
299
            LOG.fine("cancel no download dialog");
300
            //throw new InterruptedException("user canceled download & install JUnit");
301
            return null;
302
        } else if (tryAgain.equals(answer)) {
303
            LOG.fine("try again download()");
304
            return download(name);
305
        } else if (libraryManager.equals(answer)) {
306
            LOG.fine("open library manager");
307
            throw new Exception("junitlib failed/canceled to install properly, open library manager instaed");            
308
        } else {
309
            assert false : "Unknown " + answer;
310
        }
311
        assert false : "Unknown " + answer;
312
        return null;
313
    }
314
    
315
    private static JPanel searchingPanel(JLabel progressLabel, JComponent progressComponent) {
316
        JPanel panel = new JPanel();
317
        progressLabel.setLabelFor(progressComponent);
318
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
319
        panel.setLayout(layout);
320
        layout.setHorizontalGroup(
321
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
322
            .addGroup(layout.createSequentialGroup()
323
                .addContainerGap()
324
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
325
                    .addComponent(progressLabel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
326
                    .addComponent(progressComponent, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 399, Short.MAX_VALUE))
327
                .addContainerGap())
328
        );
329
        layout.setVerticalGroup(
330
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
331
            .addGroup(layout.createSequentialGroup()
332
                .addGap(96, 96, 96)
333
                .addComponent(progressLabel)
334
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
335
                .addComponent(progressComponent, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
336
                .addContainerGap(109, Short.MAX_VALUE))
337
        );
338
        return panel;
339
    }
340
    
341
    private static JPanel problemPanel(String header, String message) {
342
        JPanel panel = new JPanel();
343
        JLabel jLabel1 = new javax.swing.JLabel();
344
        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
345
        JTextArea jTextArea1 = new javax.swing.JTextArea();
346
347
        jLabel1.setFont(jLabel1.getFont().deriveFont(jLabel1.getFont().getStyle() | java.awt.Font.BOLD));
348
        jLabel1.setText(header);
349
350
        jTextArea1.setColumns(20);
351
        jTextArea1.setEditable(false);
352
        jTextArea1.setLineWrap(true);
353
        jTextArea1.setWrapStyleWord(true);
354
        jTextArea1.setRows(5);
355
        jTextArea1.setText(message);
356
        jTextArea1.setOpaque(false);
357
        jScrollPane1.setViewportView(jTextArea1);
358
359
        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(panel);
360
        panel.setLayout(layout);
361
        layout.setHorizontalGroup(
362
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
363
            .addGroup(layout.createSequentialGroup()
364
                .addContainerGap()
365
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
366
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 478, Short.MAX_VALUE)
367
                    .addGroup(layout.createSequentialGroup()
368
                        .addComponent(jLabel1)
369
                        .addGap(107, 107, 107)))
370
                .addContainerGap())
371
        );
372
        layout.setVerticalGroup(
373
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
374
            .addGroup(layout.createSequentialGroup()
375
                .addContainerGap()
376
                .addComponent(jLabel1)
377
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
378
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 133, Short.MAX_VALUE)
379
                .addGap(82, 82, 82))
380
        );
381
        return panel;
382
    }
93
    }
383
94
384
}
95
}

Return to bug 196538