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 229459
Collapse All | Expand All

(-)a/gsf.testrunner/nbproject/project.xml (-1 / +1 lines)
Lines 186-192 Link Here
186
                <friend>org.netbeans.modules.cnd.cncppunit</friend>
186
                <friend>org.netbeans.modules.cnd.cncppunit</friend>
187
                <friend>org.netbeans.modules.cnd.testrunner</friend>
187
                <friend>org.netbeans.modules.cnd.testrunner</friend>
188
                <friend>org.netbeans.modules.groovy.support</friend>
188
                <friend>org.netbeans.modules.groovy.support</friend>
189
                <friend>org.netbeans.modules.hudson</friend>
189
                <friend>org.netbeans.modules.hudson.ui</friend>
190
                <friend>org.netbeans.modules.java.testrunner</friend>
190
                <friend>org.netbeans.modules.java.testrunner</friend>
191
                <friend>org.netbeans.modules.javascript.jstestdriver</friend>
191
                <friend>org.netbeans.modules.javascript.jstestdriver</friend>
192
                <friend>org.netbeans.modules.junit</friend>
192
                <friend>org.netbeans.modules.junit</friend>
(-)a/hudson.ant/nbproject/project.xml (+8 lines)
Lines 19-24 Link Here
19
                    <build-prerequisite/>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
20
                    <compile-dependency/>
21
                    <run-dependency>
21
                    <run-dependency>
22
                        <specification-version>2.0</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
22
                        <specification-version>1.0</specification-version>
30
                        <specification-version>1.0</specification-version>
23
                    </run-dependency>
31
                    </run-dependency>
24
                </dependency>
32
                </dependency>
(-)a/hudson.ant/src/org/netbeans/modules/hudson/ant/JobCreator.java (-6 / +6 lines)
Lines 65-87 Link Here
65
import org.netbeans.modules.hudson.ant.AntBasedJobCreator.ArchivePattern;
65
import org.netbeans.modules.hudson.ant.AntBasedJobCreator.ArchivePattern;
66
import org.netbeans.modules.hudson.ant.AntBasedJobCreator.Configuration;
66
import org.netbeans.modules.hudson.ant.AntBasedJobCreator.Configuration;
67
import org.netbeans.modules.hudson.ant.AntBasedJobCreator.Target;
67
import org.netbeans.modules.hudson.ant.AntBasedJobCreator.Target;
68
import static org.netbeans.modules.hudson.ant.Bundle.*;
69
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory;
70
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory.Helper;
71
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
68
import org.netbeans.modules.hudson.spi.HudsonSCM;
72
import org.netbeans.modules.hudson.spi.HudsonSCM;
69
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory;
73
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
70
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
71
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.Helper;
72
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
73
import org.netbeans.modules.java.api.common.project.ui.customizer.ProjectSharability;
74
import org.netbeans.modules.java.api.common.project.ui.customizer.ProjectSharability;
74
import org.openide.awt.Mnemonics;
75
import org.openide.awt.Mnemonics;
75
import org.openide.filesystems.FileObject;
76
import org.openide.filesystems.FileObject;
76
import org.openide.filesystems.FileUtil;
77
import org.openide.filesystems.FileUtil;
77
import org.openide.util.Lookup;
78
import org.openide.util.Lookup;
79
import org.openide.util.NbBundle.Messages;
78
import org.openide.util.lookup.ServiceProvider;
80
import org.openide.util.lookup.ServiceProvider;
79
import org.openide.xml.XMLUtil;
81
import org.openide.xml.XMLUtil;
80
import org.w3c.dom.Document;
82
import org.w3c.dom.Document;
81
import org.w3c.dom.Element;
83
import org.w3c.dom.Element;
82
import org.xml.sax.InputSource;
84
import org.xml.sax.InputSource;
83
import static org.netbeans.modules.hudson.ant.Bundle.*;
84
import org.openide.util.NbBundle.Messages;
85
85
86
public class JobCreator extends JPanel implements ProjectHudsonJobCreator {
86
public class JobCreator extends JPanel implements ProjectHudsonJobCreator {
87
87
(-)a/hudson.git/nbproject/project.xml (-1 / +9 lines)
Lines 28-34 Link Here
28
                    <build-prerequisite/>
28
                    <build-prerequisite/>
29
                    <compile-dependency/>
29
                    <compile-dependency/>
30
                    <run-dependency>
30
                    <run-dependency>
31
                        <specification-version>1.15</specification-version>
31
                        <specification-version>2.0</specification-version>
32
                    </run-dependency>
33
                </dependency>
34
                <dependency>
35
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
36
                    <build-prerequisite/>
37
                    <compile-dependency/>
38
                    <run-dependency>
39
                        <specification-version>1.0</specification-version>
32
                    </run-dependency>
40
                    </run-dependency>
33
                </dependency>
41
                </dependency>
34
                <dependency>
42
                <dependency>
(-)a/hudson.git/src/org/netbeans/modules/hudson/git/HudsonGitSCM.java (-2 / +3 lines)
Lines 61-69 Link Here
61
import org.netbeans.modules.hudson.api.HudsonJobBuild;
61
import org.netbeans.modules.hudson.api.HudsonJobBuild;
62
import org.netbeans.modules.hudson.api.Utilities;
62
import org.netbeans.modules.hudson.api.Utilities;
63
import static org.netbeans.modules.hudson.git.Bundle.*;
63
import static org.netbeans.modules.hudson.git.Bundle.*;
64
import org.netbeans.modules.hudson.ui.api.HudsonSCMHelper;
64
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
65
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
65
import org.netbeans.modules.hudson.spi.HudsonSCM;
66
import org.netbeans.modules.hudson.spi.HudsonSCM;
66
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
67
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
67
import org.openide.util.NbBundle.Messages;
68
import org.openide.util.NbBundle.Messages;
68
import org.openide.util.lookup.ServiceProvider;
69
import org.openide.util.lookup.ServiceProvider;
69
import org.openide.windows.OutputListener;
70
import org.openide.windows.OutputListener;
Lines 96-102 Link Here
96
                // Note that all this will be wrong if the local repo is using a nondefault remote, or a branch, etc. etc.
97
                // Note that all this will be wrong if the local repo is using a nondefault remote, or a branch, etc. etc.
97
                configXmlSCM.appendChild(doc.createElement("source")).appendChild(doc.createTextNode(replacement != null ? replacement : origin.toString()));
98
                configXmlSCM.appendChild(doc.createElement("source")).appendChild(doc.createTextNode(replacement != null ? replacement : origin.toString()));
98
                // XXX consider <clean>true</clean> (though it does not seem to work)
99
                // XXX consider <clean>true</clean> (though it does not seem to work)
99
                Helper.addTrigger(doc);
100
                HudsonSCMHelper.addTrigger(doc);
100
            }
101
            }
101
            @Override public ConfigurationStatus problems() {
102
            @Override public ConfigurationStatus problems() {
102
                if (origin == null) {
103
                if (origin == null) {
(-)a/hudson.maven/nbproject/project.xml (+8 lines)
Lines 10-15 Link Here
10
                    <build-prerequisite/>
10
                    <build-prerequisite/>
11
                    <compile-dependency/>
11
                    <compile-dependency/>
12
                    <run-dependency>
12
                    <run-dependency>
13
                        <specification-version>2.0</specification-version>
14
                    </run-dependency>
15
                </dependency>
16
                <dependency>
17
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
18
                    <build-prerequisite/>
19
                    <compile-dependency/>
20
                    <run-dependency>
13
                        <specification-version>1.0</specification-version>
21
                        <specification-version>1.0</specification-version>
14
                    </run-dependency>
22
                    </run-dependency>
15
                </dependency>
23
                </dependency>
(-)a/hudson.maven/src/org/netbeans/modules/hudson/maven/HudsonProviderImpl.java (-1 / +1 lines)
Lines 46-52 Link Here
46
46
47
import java.util.Collections;
47
import java.util.Collections;
48
import org.netbeans.api.project.Project;
48
import org.netbeans.api.project.Project;
49
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
49
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
50
import org.netbeans.modules.maven.api.NbMavenProject;
50
import org.netbeans.modules.maven.api.NbMavenProject;
51
import org.netbeans.modules.maven.model.ModelOperation;
51
import org.netbeans.modules.maven.model.ModelOperation;
52
import org.netbeans.modules.maven.model.Utilities;
52
import org.netbeans.modules.maven.model.Utilities;
(-)a/hudson.maven/src/org/netbeans/modules/hudson/maven/JobCreator.java (-5 / +5 lines)
Lines 48-54 Link Here
48
import javax.swing.event.ChangeListener;
48
import javax.swing.event.ChangeListener;
49
import org.netbeans.api.project.Project;
49
import org.netbeans.api.project.Project;
50
import org.netbeans.modules.hudson.spi.HudsonSCM;
50
import org.netbeans.modules.hudson.spi.HudsonSCM;
51
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory;
51
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory;
52
import org.netbeans.modules.maven.api.NbMavenProject;
52
import org.netbeans.modules.maven.api.NbMavenProject;
53
import org.openide.util.lookup.ServiceProvider;
53
import org.openide.util.lookup.ServiceProvider;
54
import org.openide.xml.XMLUtil;
54
import org.openide.xml.XMLUtil;
Lines 73-87 Link Here
73
                return new JPanel();
73
                return new JPanel();
74
            }
74
            }
75
75
76
            public ConfigurationStatus status() {
76
            public HudsonSCM.ConfigurationStatus status() {
77
                if (scm == null) {
77
                if (scm == null) {
78
                    return Helper.noSCMError();
78
                    return ProjectHudsonJobCreatorFactory.Helper.noSCMError();
79
                }
79
                }
80
                ConfigurationStatus scmStatus = scm.problems();
80
                HudsonSCM.ConfigurationStatus scmStatus = scm.problems();
81
                if (scmStatus != null) {
81
                if (scmStatus != null) {
82
                    return scmStatus;
82
                    return scmStatus;
83
                } else {
83
                } else {
84
                    return ConfigurationStatus.valid();
84
                    return HudsonSCM.ConfigurationStatus.valid();
85
                }
85
                }
86
            }
86
            }
87
87
(-)a/hudson.maven/test/unit/src/org/netbeans/modules/hudson/maven/HudsonProviderImplTest.java (-1 / +1 lines)
Lines 45-51 Link Here
45
import org.netbeans.api.project.Project;
45
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.ProjectManager;
46
import org.netbeans.api.project.ProjectManager;
47
import org.netbeans.junit.NbTestCase;
47
import org.netbeans.junit.NbTestCase;
48
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider.Association;
48
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider.Association;
49
import org.netbeans.modules.maven.api.NbMavenProject;
49
import org.netbeans.modules.maven.api.NbMavenProject;
50
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileObject;
51
import org.openide.filesystems.FileUtil;
51
import org.openide.filesystems.FileUtil;
(-)a/hudson.mercurial/nbproject/project.xml (-1 / +9 lines)
Lines 28-34 Link Here
28
                    <build-prerequisite/>
28
                    <build-prerequisite/>
29
                    <compile-dependency/>
29
                    <compile-dependency/>
30
                    <run-dependency>
30
                    <run-dependency>
31
                        <specification-version>1.15</specification-version>
31
                        <specification-version>2.0</specification-version>
32
                    </run-dependency>
33
                </dependency>
34
                <dependency>
35
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
36
                    <build-prerequisite/>
37
                    <compile-dependency/>
38
                    <run-dependency>
39
                        <specification-version>1.0</specification-version>
32
                    </run-dependency>
40
                    </run-dependency>
33
                </dependency>
41
                </dependency>
34
                <dependency>
42
                <dependency>
(-)a/hudson.mercurial/src/org/netbeans/modules/hudson/mercurial/HudsonMercurialSCM.java (-3 / +16 lines)
Lines 64-70 Link Here
64
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
64
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
65
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType;
65
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType;
66
import org.netbeans.modules.hudson.spi.HudsonSCM;
66
import org.netbeans.modules.hudson.spi.HudsonSCM;
67
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
67
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
68
import org.netbeans.modules.hudson.ui.api.HudsonSCMHelper;
68
import org.openide.util.NbBundle.Messages;
69
import org.openide.util.NbBundle.Messages;
69
import org.openide.util.lookup.ServiceProvider;
70
import org.openide.util.lookup.ServiceProvider;
70
import org.openide.windows.OutputListener;
71
import org.openide.windows.OutputListener;
Lines 107-113 Link Here
107
                configXmlSCM.appendChild(doc.createElement("source")).appendChild(doc.createTextNode(repo)); // NOI18N
108
                configXmlSCM.appendChild(doc.createElement("source")).appendChild(doc.createTextNode(repo)); // NOI18N
108
                configXmlSCM.appendChild(doc.createElement("modules")).appendChild(doc.createTextNode("")); // NOI18N
109
                configXmlSCM.appendChild(doc.createElement("modules")).appendChild(doc.createTextNode("")); // NOI18N
109
                configXmlSCM.appendChild(doc.createElement("clean")).appendChild(doc.createTextNode("true")); // NOI18N
110
                configXmlSCM.appendChild(doc.createElement("clean")).appendChild(doc.createTextNode("true")); // NOI18N
110
                Helper.addTrigger(doc);
111
                HudsonSCMHelper.addTrigger(doc);
111
            }
112
            }
112
            public ConfigurationStatus problems() {
113
            public ConfigurationStatus problems() {
113
                if (result.isFoundInParenFolder()) {
114
                if (result.isFoundInParenFolder()) {
Lines 292-298 Link Here
292
        } else {
293
        } else {
293
            String defaultPullNoPassword = defaultPull.replaceFirst("//[^/]+(:[^/]+)?@", "//");
294
            String defaultPullNoPassword = defaultPull.replaceFirst("//[^/]+(:[^/]+)?@", "//");
294
            try {
295
            try {
295
                return repository.resolve(new URI(defaultPullNoPassword));
296
                return repository.resolve(stringToURI(defaultPullNoPassword));
296
            } catch (URISyntaxException x) {
297
            } catch (URISyntaxException x) {
297
                LOG.log(Level.FINE, "{0} is not a valid URI", defaultPullNoPassword);
298
                LOG.log(Level.FINE, "{0} is not a valid URI", defaultPullNoPassword);
298
                return null;
299
                return null;
Lines 301-306 Link Here
301
    }
302
    }
302
303
303
    /**
304
    /**
305
     * Convert string to URI. Ensure that drive letters in paths like
306
     * C:/something are not used as protocol part of the URI.
307
     */
308
    private static URI stringToURI(String s) throws URISyntaxException {
309
        String withProtocol = org.openide.util.Utilities.isWindows()
310
                && s.matches("\\w:/[^/].*") //NOI18N
311
                ? "file:/" + s //NOI18N
312
                : s;
313
        return new URI(withProtocol);
314
    }
315
316
    /**
304
     * Result of finding the default pull. Instances of this class are created
317
     * Result of finding the default pull. Instances of this class are created
305
     * by method {@link #findDefaultPull(java.io.File)}
318
     * by method {@link #findDefaultPull(java.io.File)}
306
     */
319
     */
(-)a/hudson.mercurial/src/org/netbeans/modules/hudson/mercurial/MercurialHyperlink.java (-3 / +3 lines)
Lines 58-67 Link Here
58
import java.util.regex.Matcher;
58
import java.util.regex.Matcher;
59
import java.util.regex.Pattern;
59
import java.util.regex.Pattern;
60
import org.netbeans.api.diff.StreamSource;
60
import org.netbeans.api.diff.StreamSource;
61
import org.netbeans.modules.hudson.ui.api.HudsonSCMHelper;
61
import static org.netbeans.modules.hudson.mercurial.Bundle.*;
62
import static org.netbeans.modules.hudson.mercurial.Bundle.*;
62
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile;
63
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile;
63
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType;
64
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType;
64
import org.netbeans.modules.hudson.spi.HudsonSCM.Helper;
65
import org.openide.filesystems.FileUtil;
65
import org.openide.filesystems.FileUtil;
66
import org.openide.util.NbBundle.Messages;
66
import org.openide.util.NbBundle.Messages;
67
import org.openide.util.RequestProcessor;
67
import org.openide.util.RequestProcessor;
Lines 89-101 Link Here
89
    }
89
    }
90
90
91
    public void outputLineAction(OutputEvent ev) {
91
    public void outputLineAction(OutputEvent ev) {
92
        Helper.noteWillShowDiff(file.getName());
92
        HudsonSCMHelper.noteWillShowDiff(file.getName());
93
        RP.post(new Runnable() {
93
        RP.post(new Runnable() {
94
            public void run() {
94
            public void run() {
95
                try {
95
                try {
96
                    final StreamSource before = makeSource(false);
96
                    final StreamSource before = makeSource(false);
97
                    final StreamSource after = makeSource(true);
97
                    final StreamSource after = makeSource(true);
98
                    Helper.showDiff(before, after, file.getName());
98
                    HudsonSCMHelper.showDiff(before, after, file.getName());
99
                } catch (IOException x) {
99
                } catch (IOException x) {
100
                    LOG.log(Level.INFO, null, x);
100
                    LOG.log(Level.INFO, null, x);
101
                }
101
                }
(-)a/hudson.php/nbproject/project.xml (-1 / +9 lines)
Lines 19-25 Link Here
19
                    <build-prerequisite/>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
20
                    <compile-dependency/>
21
                    <run-dependency>
21
                    <run-dependency>
22
                        <specification-version>1.23</specification-version>
22
                        <specification-version>2.0</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <specification-version>1.0</specification-version>
23
                    </run-dependency>
31
                    </run-dependency>
24
                </dependency>
32
                </dependency>
25
                <dependency>
33
                <dependency>
(-)a/hudson.php/src/org/netbeans/modules/hudson/php/HudsonJobCreator.java (-4 / +4 lines)
Lines 65-70 Link Here
65
import javax.swing.event.ChangeEvent;
65
import javax.swing.event.ChangeEvent;
66
import javax.swing.event.ChangeListener;
66
import javax.swing.event.ChangeListener;
67
import org.netbeans.api.project.Project;
67
import org.netbeans.api.project.Project;
68
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory;
69
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory.Helper;
70
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
68
import org.netbeans.modules.hudson.php.commands.PpwScript;
71
import org.netbeans.modules.hudson.php.commands.PpwScript;
69
import org.netbeans.modules.hudson.php.options.HudsonOptions;
72
import org.netbeans.modules.hudson.php.options.HudsonOptions;
70
import org.netbeans.modules.hudson.php.options.HudsonOptionsValidator;
73
import org.netbeans.modules.hudson.php.options.HudsonOptionsValidator;
Lines 72-81 Link Here
72
import org.netbeans.modules.hudson.php.ui.options.HudsonOptionsPanelController;
75
import org.netbeans.modules.hudson.php.ui.options.HudsonOptionsPanelController;
73
import org.netbeans.modules.hudson.php.xml.XmlUtils;
76
import org.netbeans.modules.hudson.php.xml.XmlUtils;
74
import org.netbeans.modules.hudson.spi.HudsonSCM;
77
import org.netbeans.modules.hudson.spi.HudsonSCM;
75
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory;
78
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
76
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
77
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.Helper;
78
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
79
import org.netbeans.modules.php.api.executable.InvalidPhpExecutableException;
79
import org.netbeans.modules.php.api.executable.InvalidPhpExecutableException;
80
import org.netbeans.modules.php.api.phpmodule.PhpModule;
80
import org.netbeans.modules.php.api.phpmodule.PhpModule;
81
import org.netbeans.modules.php.api.util.UiUtils;
81
import org.netbeans.modules.php.api.util.UiUtils;
(-)a/hudson.subversion/nbproject/project.xml (-1 / +9 lines)
Lines 19-25 Link Here
19
                    <build-prerequisite/>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
20
                    <compile-dependency/>
21
                    <run-dependency>
21
                    <run-dependency>
22
                        <specification-version>1.15</specification-version>
22
                        <specification-version>2.0</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <specification-version>1.0</specification-version>
23
                    </run-dependency>
31
                    </run-dependency>
24
                </dependency>
32
                </dependency>
25
                <dependency>
33
                <dependency>
(-)a/hudson.subversion/src/org/netbeans/modules/hudson/subversion/HudsonSubversionSCM.java (-2 / +3 lines)
Lines 59-66 Link Here
59
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile;
59
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile;
60
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType;
60
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType;
61
import org.netbeans.modules.hudson.spi.HudsonSCM;
61
import org.netbeans.modules.hudson.spi.HudsonSCM;
62
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
62
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
63
import static org.netbeans.modules.hudson.subversion.Bundle.*;
63
import static org.netbeans.modules.hudson.subversion.Bundle.*;
64
import org.netbeans.modules.hudson.ui.api.HudsonSCMHelper;
64
import org.openide.util.NbBundle.Messages;
65
import org.openide.util.NbBundle.Messages;
65
import org.openide.util.lookup.ServiceProvider;
66
import org.openide.util.lookup.ServiceProvider;
66
import org.openide.windows.OutputListener;
67
import org.openide.windows.OutputListener;
Lines 99-105 Link Here
99
                    loc.appendChild(doc.createElement("local")).appendChild(doc.createTextNode(".")); // NOI18N
100
                    loc.appendChild(doc.createElement("local")).appendChild(doc.createTextNode(".")); // NOI18N
100
                    // HUDSON-3390 would be a more attractive alternative:
101
                    // HUDSON-3390 would be a more attractive alternative:
101
                    configXmlSCM.appendChild(doc.createElement("useUpdate")).appendChild(doc.createTextNode("false")); // NOI18N
102
                    configXmlSCM.appendChild(doc.createElement("useUpdate")).appendChild(doc.createTextNode("false")); // NOI18N
102
                    Helper.addTrigger(doc);
103
                    HudsonSCMHelper.addTrigger(doc);
103
                }
104
                }
104
                public @Override ConfigurationStatus problems() {
105
                public @Override ConfigurationStatus problems() {
105
                    return null;
106
                    return null;
(-)a/hudson.subversion/src/org/netbeans/modules/hudson/subversion/SubversionHyperlink.java (-3 / +3 lines)
Lines 57-63 Link Here
57
import org.netbeans.api.diff.StreamSource;
57
import org.netbeans.api.diff.StreamSource;
58
import org.netbeans.modules.hudson.api.ConnectionBuilder;
58
import org.netbeans.modules.hudson.api.ConnectionBuilder;
59
import org.netbeans.modules.hudson.api.HudsonJob;
59
import org.netbeans.modules.hudson.api.HudsonJob;
60
import org.netbeans.modules.hudson.spi.HudsonSCM.Helper;
60
import org.netbeans.modules.hudson.ui.api.HudsonSCMHelper;
61
import org.openide.filesystems.FileUtil;
61
import org.openide.filesystems.FileUtil;
62
import org.openide.util.NbBundle;
62
import org.openide.util.NbBundle;
63
import org.openide.util.RequestProcessor;
63
import org.openide.util.RequestProcessor;
Lines 96-102 Link Here
96
    }
96
    }
97
97
98
    public @Override void outputLineAction(OutputEvent ev) {
98
    public @Override void outputLineAction(OutputEvent ev) {
99
        Helper.noteWillShowDiff(path);
99
        HudsonSCMHelper.noteWillShowDiff(path);
100
        RequestProcessor.getDefault().post(new Runnable() {
100
        RequestProcessor.getDefault().post(new Runnable() {
101
            public @Override void run() {
101
            public @Override void run() {
102
                String repo = findRepo(module);
102
                String repo = findRepo(module);
Lines 106-112 Link Here
106
                try {
106
                try {
107
                    final StreamSource before = makeSource(repo, path, startRev);
107
                    final StreamSource before = makeSource(repo, path, startRev);
108
                    final StreamSource after = makeSource(repo, path, endRev);
108
                    final StreamSource after = makeSource(repo, path, endRev);
109
                    Helper.showDiff(before, after, path);
109
                    HudsonSCMHelper.showDiff(before, after, path);
110
                } catch (IOException x) {
110
                } catch (IOException x) {
111
                    LOG.log(Level.INFO, null, x);
111
                    LOG.log(Level.INFO, null, x);
112
                }
112
                }
(-)a/hudson.subversion/test/unit/src/org/netbeans/modules/hudson/subversion/HudsonSubversionSCMTest.java (-2 / +2 lines)
Lines 51-57 Link Here
51
import java.io.Writer;
51
import java.io.Writer;
52
import org.netbeans.junit.NbTestCase;
52
import org.netbeans.junit.NbTestCase;
53
import org.netbeans.modules.hudson.spi.HudsonSCM;
53
import org.netbeans.modules.hudson.spi.HudsonSCM;
54
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
54
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
55
import org.openide.xml.XMLUtil;
55
import org.openide.xml.XMLUtil;
56
import org.w3c.dom.Document;
56
import org.w3c.dom.Document;
57
57
Lines 106-112 Link Here
106
                "</hudson.triggers.SCMTrigger>" +
106
                "</hudson.triggers.SCMTrigger>" +
107
                "</triggers>" +
107
                "</triggers>" +
108
                "</root>",
108
                "</root>",
109
                baos.toString("UTF-8").replace('"', '\'').replaceAll("\n *", ""));
109
                baos.toString("UTF-8").replace('"', '\'').replaceAll("\n *", "").replaceAll("\r|\n", ""));
110
    }
110
    }
111
111
112
    public void testSVN17Dir() throws Exception { // #210884
112
    public void testSVN17Dir() throws Exception { // #210884
(-)a/hudson.tasklist/nbproject/project.xml (-1 / +9 lines)
Lines 19-25 Link Here
19
                    <build-prerequisite/>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
20
                    <compile-dependency/>
21
                    <run-dependency>
21
                    <run-dependency>
22
                        <specification-version>1.13</specification-version>
22
                        <specification-version>2.0</specification-version>
23
                    </run-dependency>
24
                </dependency>
25
                <dependency>
26
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
27
                    <build-prerequisite/>
28
                    <compile-dependency/>
29
                    <run-dependency>
30
                        <specification-version>1.0</specification-version>
23
                    </run-dependency>
31
                    </run-dependency>
24
                </dependency>
32
                </dependency>
25
                <dependency>
33
                <dependency>
(-)a/hudson.tasklist/src/org/netbeans/modules/hudson/tasklist/HudsonScanner.java (-1 / +1 lines)
Lines 49-55 Link Here
49
import java.util.prefs.BackingStoreException;
49
import java.util.prefs.BackingStoreException;
50
import org.netbeans.api.project.Project;
50
import org.netbeans.api.project.Project;
51
import org.netbeans.modules.hudson.api.HudsonJob;
51
import org.netbeans.modules.hudson.api.HudsonJob;
52
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
52
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
53
import static org.netbeans.modules.hudson.tasklist.Bundle.*;
53
import static org.netbeans.modules.hudson.tasklist.Bundle.*;
54
import org.netbeans.spi.tasklist.PushTaskScanner;
54
import org.netbeans.spi.tasklist.PushTaskScanner;
55
import org.netbeans.spi.tasklist.Task;
55
import org.netbeans.spi.tasklist.Task;
(-)a/hudson.ui/build.xml (+5 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project basedir="." default="netbeans" name="hudson.ui">
3
    <description>Builds, tests, and runs the project org.netbeans.modules.hudson.ui</description>
4
    <import file="../nbbuild/templates/projectized.xml"/>
5
</project>
(-)a/hudson.ui/manifest.mf (+5 lines)
Line 0 Link Here
1
Manifest-Version: 1.0
2
OpenIDE-Module: org.netbeans.modules.hudson.ui
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/hudson/ui/Bundle.properties
4
OpenIDE-Module-Specification-Version: 1.0
5
(-)a/hudson.ui/nbproject/project.properties (+2 lines)
Line 0 Link Here
1
javac.source=1.6
2
javac.compilerargs=-Xlint -Xlint:-serial
(-)a/hudson.ui/nbproject/project.xml (+250 lines)
Line 0 Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<project xmlns="http://www.netbeans.org/ns/project/1">
3
    <type>org.netbeans.modules.apisupport.project</type>
4
    <configuration>
5
        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
6
            <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
7
            <module-dependencies>
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.20</specification-version>
15
                    </run-dependency>
16
                </dependency>
17
                <dependency>
18
                    <code-name-base>org.netbeans.api.java.classpath</code-name-base>
19
                    <build-prerequisite/>
20
                    <compile-dependency/>
21
                    <run-dependency>
22
                        <release-version>1</release-version>
23
                        <specification-version>1.38</specification-version>
24
                    </run-dependency>
25
                </dependency>
26
                <dependency>
27
                    <code-name-base>org.netbeans.api.progress</code-name-base>
28
                    <build-prerequisite/>
29
                    <compile-dependency/>
30
                    <run-dependency>
31
                        <release-version>1</release-version>
32
                        <specification-version>1.34</specification-version>
33
                    </run-dependency>
34
                </dependency>
35
                <dependency>
36
                    <code-name-base>org.netbeans.core.ide</code-name-base>
37
                    <build-prerequisite/>
38
                    <compile-dependency/>
39
                    <run-dependency>
40
                        <release-version>1</release-version>
41
                        <specification-version>1.33</specification-version>
42
                    </run-dependency>
43
                </dependency>
44
                <dependency>
45
                    <code-name-base>org.netbeans.libs.commons_net</code-name-base>
46
                    <build-prerequisite/>
47
                    <compile-dependency/>
48
                    <run-dependency>
49
                        <release-version>2</release-version>
50
                        <specification-version>2.11</specification-version>
51
                    </run-dependency>
52
                </dependency>
53
                <dependency>
54
                    <code-name-base>org.netbeans.modules.diff</code-name-base>
55
                    <build-prerequisite/>
56
                    <compile-dependency/>
57
                    <run-dependency>
58
                        <release-version>1</release-version>
59
                        <specification-version>1.43</specification-version>
60
                    </run-dependency>
61
                </dependency>
62
                <dependency>
63
                    <code-name-base>org.netbeans.modules.gsf.testrunner</code-name-base>
64
                    <build-prerequisite/>
65
                    <compile-dependency/>
66
                    <run-dependency>
67
                        <release-version>1</release-version>
68
                        <specification-version>1.34</specification-version>
69
                    </run-dependency>
70
                </dependency>
71
                <dependency>
72
                    <code-name-base>org.netbeans.modules.hudson</code-name-base>
73
                    <build-prerequisite/>
74
                    <compile-dependency/>
75
                    <run-dependency>
76
                        <specification-version>2.0</specification-version>
77
                    </run-dependency>
78
                </dependency>
79
                <dependency>
80
                    <code-name-base>org.netbeans.modules.keyring</code-name-base>
81
                    <build-prerequisite/>
82
                    <compile-dependency/>
83
                    <run-dependency>
84
                        <specification-version>1.16</specification-version>
85
                    </run-dependency>
86
                </dependency>
87
                <dependency>
88
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
89
                    <build-prerequisite/>
90
                    <compile-dependency/>
91
                    <run-dependency>
92
                        <release-version>1</release-version>
93
                        <specification-version>1.35</specification-version>
94
                    </run-dependency>
95
                </dependency>
96
                <dependency>
97
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
98
                    <build-prerequisite/>
99
                    <compile-dependency/>
100
                    <run-dependency>
101
                        <release-version>1</release-version>
102
                        <specification-version>1.53</specification-version>
103
                    </run-dependency>
104
                </dependency>
105
                <dependency>
106
                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
107
                    <build-prerequisite/>
108
                    <compile-dependency/>
109
                    <run-dependency>
110
                        <release-version>1</release-version>
111
                        <specification-version>1.70</specification-version>
112
                    </run-dependency>
113
                </dependency>
114
                <dependency>
115
                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
116
                    <build-prerequisite/>
117
                    <compile-dependency/>
118
                    <run-dependency>
119
                        <specification-version>1.19</specification-version>
120
                    </run-dependency>
121
                </dependency>
122
                <dependency>
123
                    <code-name-base>org.openide.actions</code-name-base>
124
                    <build-prerequisite/>
125
                    <compile-dependency/>
126
                    <run-dependency>
127
                        <specification-version>6.31</specification-version>
128
                    </run-dependency>
129
                </dependency>
130
                <dependency>
131
                    <code-name-base>org.openide.awt</code-name-base>
132
                    <build-prerequisite/>
133
                    <compile-dependency/>
134
                    <run-dependency>
135
                        <specification-version>7.58</specification-version>
136
                    </run-dependency>
137
                </dependency>
138
                <dependency>
139
                    <code-name-base>org.openide.dialogs</code-name-base>
140
                    <build-prerequisite/>
141
                    <compile-dependency/>
142
                    <run-dependency>
143
                        <specification-version>7.31</specification-version>
144
                    </run-dependency>
145
                </dependency>
146
                <dependency>
147
                    <code-name-base>org.openide.explorer</code-name-base>
148
                    <build-prerequisite/>
149
                    <compile-dependency/>
150
                    <run-dependency>
151
                        <specification-version>6.52</specification-version>
152
                    </run-dependency>
153
                </dependency>
154
                <dependency>
155
                    <code-name-base>org.openide.filesystems</code-name-base>
156
                    <build-prerequisite/>
157
                    <compile-dependency/>
158
                    <run-dependency>
159
                        <specification-version>8.7</specification-version>
160
                    </run-dependency>
161
                </dependency>
162
                <dependency>
163
                    <code-name-base>org.openide.io</code-name-base>
164
                    <build-prerequisite/>
165
                    <compile-dependency/>
166
                    <run-dependency>
167
                        <specification-version>1.37</specification-version>
168
                    </run-dependency>
169
                </dependency>
170
                <dependency>
171
                    <code-name-base>org.openide.loaders</code-name-base>
172
                    <build-prerequisite/>
173
                    <compile-dependency/>
174
                    <run-dependency>
175
                        <specification-version>7.49</specification-version>
176
                    </run-dependency>
177
                </dependency>
178
                <dependency>
179
                    <code-name-base>org.openide.nodes</code-name-base>
180
                    <build-prerequisite/>
181
                    <compile-dependency/>
182
                    <run-dependency>
183
                        <specification-version>7.35</specification-version>
184
                    </run-dependency>
185
                </dependency>
186
                <dependency>
187
                    <code-name-base>org.openide.text</code-name-base>
188
                    <build-prerequisite/>
189
                    <compile-dependency/>
190
                    <run-dependency>
191
                        <specification-version>6.56</specification-version>
192
                    </run-dependency>
193
                </dependency>
194
                <dependency>
195
                    <code-name-base>org.openide.util</code-name-base>
196
                    <build-prerequisite/>
197
                    <compile-dependency/>
198
                    <run-dependency>
199
                        <specification-version>8.31</specification-version>
200
                    </run-dependency>
201
                </dependency>
202
                <dependency>
203
                    <code-name-base>org.openide.util.lookup</code-name-base>
204
                    <build-prerequisite/>
205
                    <compile-dependency/>
206
                    <run-dependency>
207
                        <specification-version>8.21</specification-version>
208
                    </run-dependency>
209
                </dependency>
210
                <dependency>
211
                    <code-name-base>org.openide.windows</code-name-base>
212
                    <build-prerequisite/>
213
                    <compile-dependency/>
214
                    <run-dependency>
215
                        <specification-version>6.63</specification-version>
216
                    </run-dependency>
217
                </dependency>
218
            </module-dependencies>
219
            <test-dependencies>
220
                <test-type>
221
                    <name>unit</name>
222
                    <test-dependency>
223
                        <code-name-base>org.netbeans.insane</code-name-base>
224
                        <compile-dependency/>
225
                    </test-dependency>
226
                    <test-dependency>
227
                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
228
                        <compile-dependency/>
229
                    </test-dependency>
230
                    <test-dependency>
231
                        <code-name-base>org.netbeans.modules.nbjunit</code-name-base>
232
                        <compile-dependency/>
233
                    </test-dependency>
234
                </test-type>
235
            </test-dependencies>
236
            <friend-packages>
237
                <friend>org.netbeans.modules.hudson.ant</friend>
238
                <friend>org.netbeans.modules.hudson.git</friend>
239
                <friend>org.netbeans.modules.hudson.maven</friend>
240
                <friend>org.netbeans.modules.hudson.mercurial</friend>
241
                <friend>org.netbeans.modules.hudson.php</friend>
242
                <friend>org.netbeans.modules.hudson.subversion</friend>
243
                <friend>org.netbeans.modules.hudson.tasklist</friend>
244
                <friend>org.netbeans.modules.odcs.hudson</friend>
245
                <package>org.netbeans.modules.hudson.ui.api</package>
246
                <package>org.netbeans.modules.hudson.ui.spi</package>
247
            </friend-packages>
248
        </data>
249
    </configuration>
250
</project>
(-)a/hudson/src/org/netbeans/modules/hudson/ui/APITokenConnectionAuthenticator.java (-5 / +4 lines)
Lines 49-59 Link Here
49
import javax.swing.JPanel;
49
import javax.swing.JPanel;
50
import org.apache.commons.net.util.Base64;
50
import org.apache.commons.net.util.Base64;
51
import org.netbeans.api.keyring.Keyring;
51
import org.netbeans.api.keyring.Keyring;
52
import org.netbeans.modules.hudson.api.HudsonManager;
52
import org.netbeans.modules.hudson.api.HudsonVersion;
53
import org.netbeans.modules.hudson.api.HudsonVersion;
53
import org.netbeans.modules.hudson.api.Utilities;
54
import org.netbeans.modules.hudson.api.Utilities;
54
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
55
import org.netbeans.modules.hudson.spi.ConnectionAuthenticator;
55
import org.netbeans.modules.hudson.spi.ConnectionAuthenticator;
56
import static org.netbeans.modules.hudson.ui.Bundle.*;
57
import org.openide.DialogDescriptor;
56
import org.openide.DialogDescriptor;
58
import org.openide.DialogDisplayer;
57
import org.openide.DialogDisplayer;
59
import org.openide.NotifyDescriptor;
58
import org.openide.NotifyDescriptor;
Lines 107-113 Link Here
107
                LOG.log(Level.FINE, "enabled on {0}", home);
106
                LOG.log(Level.FINE, "enabled on {0}", home);
108
            }
107
            }
109
            APITokenConnectionAuthenticator panel = new APITokenConnectionAuthenticator();
108
            APITokenConnectionAuthenticator panel = new APITokenConnectionAuthenticator();
110
            String server = HudsonManagerImpl.simplifyServerLocation(home.toString(), true);
109
            String server = HudsonManager.simplifyServerLocation(home.toString(), true);
111
            String key = "tok." + server;
110
            String key = "tok." + server;
112
            String username = FormLogin.loginPrefs().get(server, null);
111
            String username = FormLogin.loginPrefs().get(server, null);
113
            if (username != null) {
112
            if (username != null) {
Lines 118-124 Link Here
118
                }
117
                }
119
            }
118
            }
120
            panel.locationField.setText(home.toString());
119
            panel.locationField.setText(home.toString());
121
            DialogDescriptor dd = new DialogDescriptor(panel, FormLogin_log_in());
120
            DialogDescriptor dd = new DialogDescriptor(panel, Bundle.FormLogin_log_in());
122
            if (DialogDisplayer.getDefault().notify(dd) != NotifyDescriptor.OK_OPTION) {
121
            if (DialogDisplayer.getDefault().notify(dd) != NotifyDescriptor.OK_OPTION) {
123
                return null;
122
                return null;
124
            }
123
            }
Lines 127-133 Link Here
127
            FormLogin.loginPrefs().put(server, username);
126
            FormLogin.loginPrefs().put(server, username);
128
            String token = new String(panel.tokField.getPassword());
127
            String token = new String(panel.tokField.getPassword());
129
            panel.tokField.setText("");
128
            panel.tokField.setText("");
130
            Keyring.save(key, token.toCharArray(), APITokenConnectionAuthenticator_password_description(home, username));
129
            Keyring.save(key, token.toCharArray(), Bundle.APITokenConnectionAuthenticator_password_description(home, username));
131
            BASIC_AUTH.put(home.toString(), new Base64(0).encodeToString((username + ':' + token).getBytes()).trim());
130
            BASIC_AUTH.put(home.toString(), new Base64(0).encodeToString((username + ':' + token).getBytes()).trim());
132
            try {
131
            try {
133
                return conn.getURL().openConnection();
132
                return conn.getURL().openConnection();
(-)a/hudson/src/org/netbeans/modules/hudson/ui/Bundle.properties (+1 lines)
Lines 39-44 Link Here
39
# However, if you add GPL Version 2 code and therefore, elected the GPL
39
# However, if you add GPL Version 2 code and therefore, elected the GPL
40
# Version 2 license, then the option applies only if the new code is
40
# Version 2 license, then the option applies only if the new code is
41
# made subject to such option by the copyright holder.
41
# made subject to such option by the copyright holder.
42
OpenIDE-Module-Name=Hudson UI
42
43
43
FormLogin.locationLabel.text=&Server:
44
FormLogin.locationLabel.text=&Server:
44
FormLogin.userLabel.text=&Username:
45
FormLogin.userLabel.text=&Username:
(-)a/hudson/src/org/netbeans/modules/hudson/ui/FormLogin.java (-5 / +5 lines)
Lines 46-58 Link Here
46
import java.util.prefs.Preferences;
46
import java.util.prefs.Preferences;
47
import javax.swing.JPanel;
47
import javax.swing.JPanel;
48
import org.netbeans.api.keyring.Keyring;
48
import org.netbeans.api.keyring.Keyring;
49
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
49
import org.netbeans.modules.hudson.api.HudsonManager;
50
import org.netbeans.modules.hudson.spi.PasswordAuthorizer;
50
import org.netbeans.modules.hudson.spi.PasswordAuthorizer;
51
import org.openide.DialogDescriptor;
51
import org.openide.DialogDescriptor;
52
import org.openide.DialogDisplayer;
52
import org.openide.DialogDisplayer;
53
import org.openide.NotifyDescriptor;
53
import org.openide.NotifyDescriptor;
54
import org.openide.util.NbBundle.Messages;
54
import org.openide.util.NbBundle.Messages;
55
import static org.netbeans.modules.hudson.ui.Bundle.*;
56
import org.openide.util.NbPreferences;
55
import org.openide.util.NbPreferences;
57
import org.openide.util.lookup.ServiceProvider;
56
import org.openide.util.lookup.ServiceProvider;
58
57
Lines 76-84 Link Here
76
            "FormLogin.log_in=Log in to Hudson",
75
            "FormLogin.log_in=Log in to Hudson",
77
            "# {0} - server location", "# {1} - user name", "FormLogin.password_description=Password for {1} on {0}"
76
            "# {0} - server location", "# {1} - user name", "FormLogin.password_description=Password for {1} on {0}"
78
        })
77
        })
78
        @Override
79
        public String[] authorize(URL home) {
79
        public String[] authorize(URL home) {
80
            FormLogin panel = new FormLogin();
80
            FormLogin panel = new FormLogin();
81
            String server = HudsonManagerImpl.simplifyServerLocation(home.toString(), true);
81
            String server = HudsonManager.simplifyServerLocation(home.toString(), true);
82
            String username = loginPrefs().get(server, null);
82
            String username = loginPrefs().get(server, null);
83
            if (username != null) {
83
            if (username != null) {
84
                panel.userField.setText(username);
84
                panel.userField.setText(username);
Lines 88-94 Link Here
88
                }
88
                }
89
            }
89
            }
90
            panel.locationField.setText(home.toString());
90
            panel.locationField.setText(home.toString());
91
            DialogDescriptor dd = new DialogDescriptor(panel, FormLogin_log_in());
91
            DialogDescriptor dd = new DialogDescriptor(panel, Bundle.FormLogin_log_in());
92
            if (DialogDisplayer.getDefault().notify(dd) != NotifyDescriptor.OK_OPTION) {
92
            if (DialogDisplayer.getDefault().notify(dd) != NotifyDescriptor.OK_OPTION) {
93
                return null;
93
                return null;
94
            }
94
            }
Lines 96-102 Link Here
96
            loginPrefs().put(server, username);
96
            loginPrefs().put(server, username);
97
            String password = new String(panel.passField.getPassword());
97
            String password = new String(panel.passField.getPassword());
98
            panel.passField.setText("");
98
            panel.passField.setText("");
99
            Keyring.save(server, password.toCharArray(), FormLogin_password_description(home, username));
99
            Keyring.save(server, password.toCharArray(), Bundle.FormLogin_password_description(home, username));
100
            return new String[] {username, password};
100
            return new String[] {username, password};
101
        }
101
        }
102
    }
102
    }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/AddTestInstanceAction.java (-9 / +11 lines)
Lines 53-66 Link Here
53
import org.netbeans.api.progress.ProgressHandle;
53
import org.netbeans.api.progress.ProgressHandle;
54
import org.netbeans.api.progress.ProgressHandleFactory;
54
import org.netbeans.api.progress.ProgressHandleFactory;
55
import org.netbeans.modules.hudson.api.ConnectionBuilder;
55
import org.netbeans.modules.hudson.api.ConnectionBuilder;
56
import org.netbeans.modules.hudson.api.UI;
56
import org.netbeans.modules.hudson.api.HudsonManager;
57
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
57
import org.netbeans.modules.hudson.ui.api.UI;
58
import org.openide.DialogDisplayer;
58
import org.openide.DialogDisplayer;
59
import org.openide.NotifyDescriptor;
59
import org.openide.NotifyDescriptor;
60
import org.openide.util.Cancellable;
60
import org.openide.util.Cancellable;
61
import org.openide.util.NbBundle.Messages;
61
import org.openide.util.NbBundle.Messages;
62
import org.openide.util.RequestProcessor;
62
import org.openide.util.RequestProcessor;
63
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
64
63
65
/**
64
/**
66
 * #161911: downloads & runs latest hudson.war and configures it for you.
65
 * #161911: downloads & runs latest hudson.war and configures it for you.
Lines 71-79 Link Here
71
70
72
    @Messages("AddTestInstanceAction.label=Try Hudson on &Localhost")
71
    @Messages("AddTestInstanceAction.label=Try Hudson on &Localhost")
73
    public AddTestInstanceAction() {
72
    public AddTestInstanceAction() {
74
        super(AddTestInstanceAction_label());
73
        super(Bundle.AddTestInstanceAction_label());
75
    }
74
    }
76
75
76
    @Override
77
    public void actionPerformed(ActionEvent e) {
77
    public void actionPerformed(ActionEvent e) {
78
        RequestProcessor.getDefault().post(this);
78
        RequestProcessor.getDefault().post(this);
79
    }
79
    }
Lines 84-89 Link Here
84
        "AddTestInstanceAction.starting=Downloading & running Hudson...",
84
        "AddTestInstanceAction.starting=Downloading & running Hudson...",
85
        "AddTestInstanceAction.instance_name=Local Test Server"
85
        "AddTestInstanceAction.instance_name=Local Test Server"
86
    })
86
    })
87
    @Override
87
    public void run() {
88
    public void run() {
88
        // XXX could use JavaPlatformManager.default.defaultPlatform.findTool("javaws") if could depend on java.platform
89
        // XXX could use JavaPlatformManager.default.defaultPlatform.findTool("javaws") if could depend on java.platform
89
        File javaHome = new File(System.getProperty("java.home"));
90
        File javaHome = new File(System.getProperty("java.home"));
Lines 96-118 Link Here
96
            javaws = new File(bindir, "javaws");
97
            javaws = new File(bindir, "javaws");
97
        }
98
        }
98
        if (!javaws.isFile()) {
99
        if (!javaws.isFile()) {
99
            warning(AddTestInstanceAction_no_javaws(javaws));
100
            warning(Bundle.AddTestInstanceAction_no_javaws(javaws));
100
            return;
101
            return;
101
        }
102
        }
102
        try {
103
        try {
103
            int exit = new ProcessBuilder(javaws.getAbsolutePath(), "https://hudson.dev.java.net/hudson.jnlp").start().waitFor();
104
            int exit = new ProcessBuilder(javaws.getAbsolutePath(), "https://hudson.dev.java.net/hudson.jnlp").start().waitFor();
104
            if (exit != 0) {
105
            if (exit != 0) {
105
                warning(AddTestInstanceAction_could_not_run());
106
                warning(Bundle.AddTestInstanceAction_could_not_run());
106
                return;
107
                return;
107
            }
108
            }
108
        } catch (Exception x) {
109
        } catch (Exception x) {
109
            warning(AddTestInstanceAction_could_not_run());
110
            warning(Bundle.AddTestInstanceAction_could_not_run());
110
            LOG.log(Level.INFO, null, x);
111
            LOG.log(Level.INFO, null, x);
111
            return;
112
            return;
112
        }
113
        }
113
        final AtomicBoolean cancelled = new AtomicBoolean();
114
        final AtomicBoolean cancelled = new AtomicBoolean();
114
        ProgressHandle progress = ProgressHandleFactory.createHandle(
115
        ProgressHandle progress = ProgressHandleFactory.createHandle(
115
                AddTestInstanceAction_starting(), new Cancellable() {
116
                Bundle.AddTestInstanceAction_starting(), new Cancellable() {
117
            @Override
116
            public boolean cancel() {
118
            public boolean cancel() {
117
                cancelled.set(true);
119
                cancelled.set(true);
118
                return true;
120
                return true;
Lines 130-136 Link Here
130
                try {
132
                try {
131
                    new ConnectionBuilder().url(localhost).connection();
133
                    new ConnectionBuilder().url(localhost).connection();
132
                    // Success!
134
                    // Success!
133
                    HudsonInstanceImpl.createHudsonInstance(AddTestInstanceAction_instance_name(), localhost, "1"); // NOI18N
135
                    HudsonManager.addInstance(Bundle.AddTestInstanceAction_instance_name(), localhost, 1, true); // NOI18N
134
                    UI.selectNode(localhost);
136
                    UI.selectNode(localhost);
135
                    break;
137
                    break;
136
                } catch (IOException x) {
138
                } catch (IOException x) {
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/Bundle.properties (-11 / +49 lines)
Lines 43-55 Link Here
43
LBL_Add_Instance=&Add Hudson Instance...
43
LBL_Add_Instance=&Add Hudson Instance...
44
44
45
LBL_StartJobAction=&Start Job
45
LBL_StartJobAction=&Start Job
46
47
CreateJobPanel.projectLabel.text=&Project to Build:
48
CreateJobPanel.nameLabel.text=Build &Name:
49
CreateJobPanel.browse.text=&Browse...
50
CreateJobPanel.serverLabel.text=Build &Server:
51
CreateJobPanel.addServer.text=&Add...
52
CreateJobPanel.explanationLabel.text=<html>Build Server will automatically get the sources and libraries from the same\n<br>source code repository and run the same build targets as your local project.
53
ShowChanges.label=Show Changes
46
ShowChanges.label=Show Changes
54
ShowChanges.no_changes=No changes.
47
ShowChanges.no_changes=No changes.
55
# {0} - job #build
48
# {0} - job #build
Lines 59-67 Link Here
59
CreateJobPanel.unknown_project_type=The IDE does not know how to set up a job for this project.
52
CreateJobPanel.unknown_project_type=The IDE does not know how to set up a job for this project.
60
CreateJobPanel.name_taken=This name is taken. Pick another.
53
CreateJobPanel.name_taken=This name is taken. Pick another.
61
CreateJobPanel.already_associated=This project already seems to be associated with a Hudson job.
54
CreateJobPanel.already_associated=This project already seems to be associated with a Hudson job.
55
CreateJobPanel.AccessibleContext.accessibleDescription=Create a new build job for a project.
56
CreateJobPanel.explanationLabel.text=<html>Build Server will automatically get the sources and libraries from the same\n<br>source code repository and run the same build targets as your local project.
57
CreateJobPanel.browse.AccessibleContext.accessibleDescription=Select a project to build from disk.
58
CreateJobPanel.browse.text=&Browse...
59
CreateJobPanel.project.AccessibleContext.accessibleDescription=Select project for which to create job.
60
CreateJobPanel.nameLabel.text=Build &Name:
62
CreateJobPanel.addServer.AccessibleContext.accessibleDescription=Add a new build server.
61
CreateJobPanel.addServer.AccessibleContext.accessibleDescription=Add a new build server.
63
CreateJobPanel.browse.AccessibleContext.accessibleDescription=Select a project to build from disk.
62
CreateJobPanel.addServer.text=&Add...
63
CreateJobPanel.projectLabel.text=&Project to Build:
64
CreateJobPanel.name.AccessibleContext.accessibleDescription=Name of new job.
65
CreateJobPanel.serverLabel.text=Build &Server:
66
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
67
68
# Copyright 2013 Oracle and/or its affiliates. All rights reserved.
69
70
# Oracle and Java are registered trademarks of Oracle and/or its affiliates.
71
# Other names may be trademarks of their respective owners.
72
73
# The contents of this file are subject to the terms of either the GNU
74
# General Public License Version 2 only ("GPL") or the Common
75
# Development and Distribution License("CDDL") (collectively, the
76
# "License"). You may not use this file except in compliance with the
77
# License. You can obtain a copy of the License at
78
# http://www.netbeans.org/cddl-gplv2.html
79
# or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
80
# specific language governing permissions and limitations under the
81
# License.  When distributing the software, include this License Header
82
# Notice in each file and include the License file at
83
# nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
84
# particular file as subject to the "Classpath" exception as provided
85
# by Oracle in the GPL Version 2 section of the License file that
86
# accompanied this code. If applicable, add the following below the
87
# License Header, with the fields enclosed by brackets [] replaced by
88
# your own identifying information:
89
# "Portions Copyrighted [year] [name of copyright owner]"
90
91
# If you wish your version of this file to be governed by only the CDDL
92
# or only the GPL Version 2, indicate your decision by adding
93
# "[Contributor] elects to include this software in this distribution
94
# under the [CDDL or GPL Version 2] license." If you do not indicate a
95
# single choice of license, a recipient has the option to distribute
96
# your version of this file under either the CDDL, the GPL Version 2 or
97
# to extend the choice of license to its licensees as provided above.
98
# However, if you add GPL Version 2 code and therefore, elected the GPL
99
# Version 2 license, then the option applies only if the new code is
100
# made subject to such option by the copyright holder.
101
102
# Contributor(s):
103
104
# Portions Copyrighted 2013 Sun Microsystems, Inc.
64
CreateJobPanel.server.AccessibleContext.accessibleDescription=Select server on which to create job.
105
CreateJobPanel.server.AccessibleContext.accessibleDescription=Select server on which to create job.
65
CreateJobPanel.project.AccessibleContext.accessibleDescription=Select project for which to create job.
66
CreateJobPanel.name.AccessibleContext.accessibleDescription=Name of new job.
67
CreateJobPanel.AccessibleContext.accessibleDescription=Create a new build job for a project.
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/CreateJob.java (-19 / +14 lines)
Lines 60-72 Link Here
60
import org.netbeans.api.project.ui.OpenProjects;
60
import org.netbeans.api.project.ui.OpenProjects;
61
import org.netbeans.modules.hudson.api.ConnectionBuilder;
61
import org.netbeans.modules.hudson.api.ConnectionBuilder;
62
import org.netbeans.modules.hudson.api.HudsonInstance;
62
import org.netbeans.modules.hudson.api.HudsonInstance;
63
import org.netbeans.modules.hudson.api.UI;
63
import org.netbeans.modules.hudson.api.HudsonManager;
64
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
65
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
66
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
67
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
68
import org.netbeans.modules.hudson.api.Utilities;
64
import org.netbeans.modules.hudson.api.Utilities;
69
import org.netbeans.modules.hudson.util.UsageLogging;
65
import org.netbeans.modules.hudson.ui.api.UI;
66
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
67
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
68
import org.netbeans.modules.hudson.ui.util.UsageLogging;
70
import org.openide.DialogDescriptor;
69
import org.openide.DialogDescriptor;
71
import org.openide.DialogDisplayer;
70
import org.openide.DialogDisplayer;
72
import org.openide.NotifyDescriptor;
71
import org.openide.NotifyDescriptor;
Lines 77-83 Link Here
77
import org.openide.util.Exceptions;
76
import org.openide.util.Exceptions;
78
import org.openide.util.NbBundle;
77
import org.openide.util.NbBundle;
79
import org.openide.util.NbBundle.Messages;
78
import org.openide.util.NbBundle.Messages;
80
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
81
import org.openide.util.RequestProcessor;
79
import org.openide.util.RequestProcessor;
82
import org.openide.xml.XMLUtil;
80
import org.openide.xml.XMLUtil;
83
import org.w3c.dom.Document;
81
import org.w3c.dom.Document;
Lines 111-128 Link Here
111
        "CreateJob.create=Create"
109
        "CreateJob.create=Create"
112
    })
110
    })
113
    @Override public void actionPerformed(ActionEvent e) {
111
    @Override public void actionPerformed(ActionEvent e) {
114
        if (instance instanceof HudsonInstanceImpl) {
112
        Action custom = instance.getPersistence().getNewJobAction();
115
            Action custom = ((HudsonInstanceImpl) instance)
113
        if (custom != null) {
116
                    .getPersistence().getNewJobAction();
114
            custom.actionPerformed(e);
117
            if (custom != null) {
115
            return;
118
                custom.actionPerformed(e);
119
                return;
120
            }
121
        }
116
        }
122
        final CreateJobPanel panel = new CreateJobPanel();
117
        final CreateJobPanel panel = new CreateJobPanel();
123
        final DialogDescriptor dd = new DialogDescriptor(panel, CreateJob_title());
118
        final DialogDescriptor dd = new DialogDescriptor(panel, Bundle.CreateJob_title());
124
        final AtomicReference<Dialog> dialog = new AtomicReference<Dialog>();
119
        final AtomicReference<Dialog> dialog = new AtomicReference<Dialog>();
125
        final JButton createButton = new JButton(CreateJob_create());
120
        final JButton createButton = new JButton(Bundle.CreateJob_create());
126
        createButton.addActionListener(new ActionListener() {
121
        createButton.addActionListener(new ActionListener() {
127
            @Override public void actionPerformed(ActionEvent e) {
122
            @Override public void actionPerformed(ActionEvent e) {
128
                RequestProcessor.getDefault().post(new Runnable() {
123
                RequestProcessor.getDefault().post(new Runnable() {
Lines 144-150 Link Here
144
        if (instance != null) {
139
        if (instance != null) {
145
            _instance = instance;
140
            _instance = instance;
146
        } else {
141
        } else {
147
            Collection<? extends HudsonInstance> instances = HudsonManagerImpl.getDefault().getInstances();
142
            Collection<? extends HudsonInstance> instances = HudsonManager.getAllInstances();
148
            _instance = instances.isEmpty() ? null : instances.iterator().next();
143
            _instance = instances.isEmpty() ? null : instances.iterator().next();
149
        }
144
        }
150
        panel.init(dd, _instance);
145
        panel.init(dd, _instance);
Lines 174-180 Link Here
174
                    postData(baos.toByteArray()).
169
                    postData(baos.toByteArray()).
175
                    httpConnection().disconnect();
170
                    httpConnection().disconnect();
176
            URLDisplayer.getDefault().showURL(new URL(instance.getUrl() + "job/" + Utilities.uriEncode(name) + "/")); // NOI18N
171
            URLDisplayer.getDefault().showURL(new URL(instance.getUrl() + "job/" + Utilities.uriEncode(name) + "/")); // NOI18N
177
            ((HudsonInstanceImpl) instance).synchronize(false);
172
            instance.synchronize(false);
178
            ProjectHudsonProvider.getDefault().recordAssociation(project,
173
            ProjectHudsonProvider.getDefault().recordAssociation(project,
179
                    new ProjectHudsonProvider.Association(instance.getUrl(), name));
174
                    new ProjectHudsonProvider.Association(instance.getUrl(), name));
180
            OpenProjects.getDefault().open(new Project[] {project}, false);
175
            OpenProjects.getDefault().open(new Project[] {project}, false);
Lines 185-191 Link Here
185
        } catch (ProjectHudsonJobCreator.SilentIOException x) {
180
        } catch (ProjectHudsonJobCreator.SilentIOException x) {
186
            Logger.getLogger(CreateJob.class.getName()).log(Level.INFO, null, x);
181
            Logger.getLogger(CreateJob.class.getName()).log(Level.INFO, null, x);
187
        } catch (IOException x) {
182
        } catch (IOException x) {
188
            Exceptions.attachLocalizedMessage(x, CreateJob_failure());
183
            Exceptions.attachLocalizedMessage(x, Bundle.CreateJob_failure());
189
            Logger.getLogger(CreateJob.class.getName()).log(Level.WARNING, null, x);
184
            Logger.getLogger(CreateJob.class.getName()).log(Level.WARNING, null, x);
190
        }
185
        }
191
    }
186
    }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/CreateJobPanel.java (-6 / +6 lines)
Lines 65-75 Link Here
65
import org.netbeans.api.project.ui.OpenProjects;
65
import org.netbeans.api.project.ui.OpenProjects;
66
import org.netbeans.modules.hudson.api.HudsonInstance;
66
import org.netbeans.modules.hudson.api.HudsonInstance;
67
import org.netbeans.modules.hudson.api.HudsonJob;
67
import org.netbeans.modules.hudson.api.HudsonJob;
68
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
68
import org.netbeans.modules.hudson.api.HudsonManager;
69
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory;
69
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory;
70
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
70
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
71
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
71
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonJobCreatorFactory.ProjectHudsonJobCreator;
72
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
72
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
73
import org.netbeans.modules.hudson.ui.wizard.InstanceDialog;
73
import org.netbeans.modules.hudson.ui.wizard.InstanceDialog;
74
import org.netbeans.spi.project.ui.support.ProjectChooser;
74
import org.netbeans.spi.project.ui.support.ProjectChooser;
75
import org.openide.NotificationLineSupport;
75
import org.openide.NotificationLineSupport;
Lines 181-187 Link Here
181
    }
181
    }
182
182
183
    private void updateServerModel() {
183
    private void updateServerModel() {
184
        server.setModel(new DefaultComboBoxModel(HudsonManagerImpl.getDefault().getInstances().toArray()));
184
        server.setModel(new DefaultComboBoxModel(HudsonManager.getAllInstances().toArray()));
185
    }
185
    }
186
186
187
    private void computeTakenNames() {
187
    private void computeTakenNames() {
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/Hyperlinker.java (-170 / +8 lines)
Lines 42-81 Link Here
42
42
43
package org.netbeans.modules.hudson.ui.actions;
43
package org.netbeans.modules.hudson.ui.actions;
44
44
45
import java.awt.Toolkit;
46
import java.io.File;
47
import java.io.IOException;
48
import java.net.MalformedURLException;
49
import java.net.URL;
50
import java.util.ArrayList;
45
import java.util.ArrayList;
51
import java.util.List;
46
import java.util.List;
52
import java.util.logging.Level;
53
import java.util.logging.Logger;
47
import java.util.logging.Logger;
54
import java.util.regex.Matcher;
55
import java.util.regex.Pattern;
56
import org.netbeans.api.project.Project;
57
import org.netbeans.modules.hudson.api.HudsonJob;
48
import org.netbeans.modules.hudson.api.HudsonJob;
58
import org.netbeans.modules.hudson.spi.HudsonLogger;
49
import org.netbeans.modules.hudson.spi.HudsonLogger;
59
import org.netbeans.modules.hudson.spi.HudsonLogger.HudsonLogSession;
50
import org.netbeans.modules.hudson.spi.HudsonLogger.HudsonLogSession;
60
import org.netbeans.modules.hudson.spi.HudsonSCM;
61
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
62
import org.openide.awt.HtmlBrowser.URLDisplayer;
63
import org.openide.awt.StatusDisplayer;
64
import org.openide.filesystems.FileObject;
65
import org.openide.filesystems.FileUtil;
66
import org.openide.util.Lookup;
51
import org.openide.util.Lookup;
67
import org.openide.util.NbBundle.Messages;
68
import org.openide.util.RequestProcessor;
69
import org.openide.util.lookup.ServiceProvider;
52
import org.openide.util.lookup.ServiceProvider;
70
import org.openide.windows.OutputEvent;
71
import org.openide.windows.OutputListener;
72
import org.openide.windows.OutputWriter;
53
import org.openide.windows.OutputWriter;
73
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
74
54
75
/**
55
/**
76
 * Manages warning/error/stack trace hyperlinking in the Output Window.
56
 * Manages warning/error/stack trace hyperlinking in the Output Window.
77
 */
57
 */
78
public class Hyperlinker {
58
public final class Hyperlinker {
79
59
80
    private static final Logger LOG = Logger.getLogger(Hyperlinker.class.getName());
60
    private static final Logger LOG = Logger.getLogger(Hyperlinker.class.getName());
81
61
Lines 95-258 Link Here
95
                break;
75
                break;
96
            }
76
            }
97
        }
77
        }
98
        // PlainLogger is last and always handles it
78
        // DefaultLogger is last and always handles it
99
    }
79
    }
100
80
101
    static class PlainLoggerLogic {
81
    @ServiceProvider(service = HudsonLogger.class, position = Integer.MAX_VALUE)
102
        private static final Pattern REMOTE_URL = Pattern.compile("\\b(https?://[^\\s)>]+)");
82
    public static final class DefaultLogger implements HudsonLogger {
103
        private final HudsonJob job;
104
        /** Looks for errors mentioning workspace files. Prefix captures Maven's [WARNING], Ant's [javac], etc. */
105
        private final Pattern hyperlinkable;
106
        PlainLoggerLogic(HudsonJob job, String jobName) {
107
            this.job = job;
108
            // XXX support Windows build servers (using backslashes)
109
            String jobNameQ = Pattern.quote(jobName);
110
            hyperlinkable = Pattern.compile("\\s*(?:\\[.+\\] )?/.+?/(?:jobs/" + jobNameQ + "/workspace|workspace/" + jobNameQ + // NOI18N
111
                    ")/([^:]+):(?:\\[?([0-9]+)[:,](?:([0-9]+)[]:])?)? (?:warning: )?(.+)"); // NOI18N
112
        }
113
        OutputListener findHyperlink(String line) {
114
            try {
115
                Matcher m = hyperlinkable.matcher(line);
116
                if (m.matches()) {
117
                    final String path = m.group(1);
118
                    final int row = m.group(2) != null ? Integer.parseInt(m.group(2)) - 1 : -1;
119
                    final int col = m.group(3) != null ? Integer.parseInt(m.group(3)) - 1 : -1;
120
                    final String message = m.group(4);
121
                    return new Hyperlink(job, path, message, row, col);
122
                }
123
                m = REMOTE_URL.matcher(line);
124
                if (m.matches()) {
125
                    return new URLHyperlink(new URL(m.group()));
126
                }
127
            } catch (MalformedURLException x) {
128
                LOG.log(Level.FINE, null, x);
129
            }
130
            return null;
131
        }
132
    }
133
83
134
    @ServiceProvider(service=HudsonLogger.class)
84
        @Override
135
    public static final class PlainLogger implements HudsonLogger {
85
        public HudsonLogSession createSession(HudsonJob job) {
136
        public HudsonLogSession createSession(final HudsonJob job) {
137
            return new HudsonLogSession() {
86
            return new HudsonLogSession() {
138
                final PlainLoggerLogic logic = new PlainLoggerLogic(job, job.getName());
87
88
                @Override
139
                public boolean handle(String line, OutputWriter stream) {
89
                public boolean handle(String line, OutputWriter stream) {
140
                    OutputListener link = logic.findHyperlink(line);
141
                    if (link != null) {
142
                        try {
143
                            stream.println(line, link);
144
                            return true;
145
                        } catch (IOException x) {
146
                            LOG.log(Level.INFO, null, x);
147
                        }
148
                    }
149
                    stream.println(line);
90
                    stream.println(line);
150
                    return true;
91
                    return true;
151
                }
92
                }
152
            };
93
            };
153
        }
94
        }
154
    }
95
    }
155
156
    private static class Hyperlink implements OutputListener {
157
158
        private static final RequestProcessor RP = new RequestProcessor(Hyperlink.class);
159
160
        private final HudsonJob job;
161
        private final String path;
162
        private final String message;
163
        private final int row;
164
        private final int col;
165
166
        public Hyperlink(HudsonJob job, String path, String message, int row, int col) {
167
            this.job = job;
168
            this.path = path;
169
            this.message = message;
170
            this.row = row;
171
            this.col = col;
172
        }
173
174
        public void outputLineAction(OutputEvent ev) {
175
            acted(true);
176
        }
177
178
        public void outputLineSelected(OutputEvent ev) {
179
            acted(false);
180
        }
181
182
        @Messages({"# {0} - file path in workspace", "Hyperlinker.looking_for=Looking for {0}...", "# {0} - file path in workspace", "Hyperlinker.not_found=No file {0} found in remote workspace."})
183
        private void acted(final boolean force) {
184
            RP.post(new Runnable() {
185
                public void run() {
186
                    FileObject f = null;
187
                    Project p = ProjectHudsonProvider.getDefault().findAssociatedProject(ProjectHudsonProvider.Association.forJob(job));
188
                    if (p != null) {
189
                        String localPath = null;
190
                        File localRoot = FileUtil.toFile(p.getProjectDirectory());
191
                        if (localRoot != null) {
192
                            for (HudsonSCM scm : Lookup.getDefault().lookupAll(HudsonSCM.class)) {
193
                                localPath = scm.translateWorkspacePath(job, path, localRoot);
194
                                if (localPath != null) {
195
                                    LOG.log(Level.FINE, "Translating remote path {0} to {1} using {2}", new Object[] {path, localPath, scm});
196
                                    break;
197
                                }
198
                            }
199
                        }
200
                        if (localPath == null) {
201
                            LOG.fine("Falling back to guess that remote workspace is a project root");
202
                            localPath = path;
203
                        }
204
                        // XXX permit localPath to include ../ segments; for Hg this is reasonable
205
                        f = p.getProjectDirectory().getFileObject(localPath);
206
                        LOG.log(Level.FINE, "Tried to find local file in {0} at {1} using {2}", new Object[] {p, f, localPath});
207
                        // XXX #159829: consider aligning local line number with remote line number somehow
208
                    }
209
                    if (f == null) {
210
                        StatusDisplayer.getDefault().setStatusText(Hyperlinker_looking_for(path));
211
                        f = job.getRemoteWorkspace().findResource(path);
212
                        LOG.log(Level.FINE, "Tried to find remote file at {0} using {1}", new Object[] {f, path});
213
                    }
214
                    if (f == null) {
215
                        if (force) {
216
                        StatusDisplayer.getDefault().setStatusText(Hyperlinker_not_found(path));
217
                            Toolkit.getDefaultToolkit().beep();
218
                        }
219
                        return;
220
                    }
221
                    // XXX could be useful to select this file in the workspace node (see related #159838)
222
                    StatusDisplayer.getDefault().setStatusText(message);
223
                    HudsonLogger.Helper.openAt(f, row, col, force);
224
                }
225
            });
226
        }
227
228
        public void outputLineCleared(OutputEvent ev) {}
229
230
        public @Override String toString() {
231
            return path + ":" + row + ":" + col + ":" + message; // NOI18N
232
        }
233
        
234
    }
235
236
    private static class URLHyperlink implements OutputListener {
237
238
        private final URL u;
239
240
        URLHyperlink(URL u) {
241
            this.u = u;
242
        }
243
244
        public void outputLineAction(OutputEvent ev) {
245
            URLDisplayer.getDefault().showURL(u);
246
        }
247
248
        public void outputLineSelected(OutputEvent ev) {}
249
250
        public void outputLineCleared(OutputEvent ev) {}
251
252
        public @Override String toString() {
253
            return u.toString();
254
        }
255
256
    }
257
258
}
96
}
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/LogInAction.java (-3 / +2 lines)
Lines 51-57 Link Here
51
import javax.swing.AbstractAction;
51
import javax.swing.AbstractAction;
52
import org.netbeans.modules.hudson.api.ConnectionBuilder;
52
import org.netbeans.modules.hudson.api.ConnectionBuilder;
53
import org.netbeans.modules.hudson.api.HudsonInstance;
53
import org.netbeans.modules.hudson.api.HudsonInstance;
54
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
55
import org.netbeans.modules.hudson.spi.ConnectionAuthenticator;
54
import org.netbeans.modules.hudson.spi.ConnectionAuthenticator;
56
import org.openide.awt.ActionRegistration;
55
import org.openide.awt.ActionRegistration;
57
import org.openide.awt.ActionID;
56
import org.openide.awt.ActionID;
Lines 69-77 Link Here
69
    private static final Logger LOG = Logger.getLogger(LogInAction.class.getName());
68
    private static final Logger LOG = Logger.getLogger(LogInAction.class.getName());
70
    private static final RequestProcessor RP = new RequestProcessor(LogInAction.class);
69
    private static final RequestProcessor RP = new RequestProcessor(LogInAction.class);
71
70
72
    private final HudsonInstanceImpl instance;
71
    private final HudsonInstance instance;
73
    
72
    
74
    public LogInAction(HudsonInstanceImpl instance) {
73
    public LogInAction(HudsonInstance instance) {
75
        super(Bundle.CTL_LogInAction());
74
        super(Bundle.CTL_LogInAction());
76
        this.instance = instance;
75
        this.instance = instance;
77
    }
76
    }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/OpenUrlAction.java (-4 / +3 lines)
Lines 53-65 Link Here
53
import javax.swing.AbstractAction;
53
import javax.swing.AbstractAction;
54
import java.net.MalformedURLException;
54
import java.net.MalformedURLException;
55
import java.net.URL;
55
import java.net.URL;
56
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
56
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
57
import org.openide.awt.ActionID;
57
import org.openide.awt.ActionID;
58
import org.openide.awt.ActionReference;
58
import org.openide.awt.ActionReference;
59
import org.openide.awt.ActionRegistration;
59
import org.openide.awt.ActionRegistration;
60
import org.openide.awt.HtmlBrowser.URLDisplayer;
60
import org.openide.awt.HtmlBrowser.URLDisplayer;
61
import org.openide.util.NbBundle.Messages;
61
import org.openide.util.NbBundle.Messages;
62
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
63
62
64
/**
63
/**
65
 * Action which displays selected job in browser.
64
 * Action which displays selected job in browser.
Lines 68-74 Link Here
68
@ActionRegistration(displayName="#LBL_OpenInBrowserAction", iconInMenu=false)
67
@ActionRegistration(displayName="#LBL_OpenInBrowserAction", iconInMenu=false)
69
@ActionReference(path=HudsonInstance.ACTION_PATH, position=600)
68
@ActionReference(path=HudsonInstance.ACTION_PATH, position=600)
70
@Messages("LBL_OpenInBrowserAction=&Open in Browser")
69
@Messages("LBL_OpenInBrowserAction=&Open in Browser")
71
public class OpenUrlAction extends AbstractAction {
70
public final class OpenUrlAction extends AbstractAction {
72
71
73
    public static Action forOpenable(OpenableInBrowser openable) {
72
    public static Action forOpenable(OpenableInBrowser openable) {
74
        return new OpenUrlAction(Collections.singletonList(openable));
73
        return new OpenUrlAction(Collections.singletonList(openable));
Lines 77-83 Link Here
77
    private final List<OpenableInBrowser> openables;
76
    private final List<OpenableInBrowser> openables;
78
77
79
    public OpenUrlAction(List<OpenableInBrowser> openables) {
78
    public OpenUrlAction(List<OpenableInBrowser> openables) {
80
        super(LBL_OpenInBrowserAction());
79
        super(Bundle.LBL_OpenInBrowserAction());
81
        this.openables = openables;
80
        this.openables = openables;
82
    }
81
    }
83
    
82
    
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/PersistInstanceAction.java (-8 / +8 lines)
Lines 51-57 Link Here
51
import java.awt.event.ActionEvent;
51
import java.awt.event.ActionEvent;
52
import java.util.Collections;
52
import java.util.Collections;
53
import org.netbeans.modules.hudson.api.HudsonInstance;
53
import org.netbeans.modules.hudson.api.HudsonInstance;
54
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
54
import org.netbeans.modules.hudson.api.Utilities;
55
import org.openide.awt.ActionID;
55
import org.openide.awt.ActionID;
56
import org.openide.awt.ActionReference;
56
import org.openide.awt.ActionReference;
57
import org.openide.awt.ActionRegistration;
57
import org.openide.awt.ActionRegistration;
Lines 67-85 Link Here
67
public class PersistInstanceAction extends AbstractAction implements ContextAwareAction {
67
public class PersistInstanceAction extends AbstractAction implements ContextAwareAction {
68
68
69
    public PersistInstanceAction() {
69
    public PersistInstanceAction() {
70
        this(Collections.<HudsonInstanceImpl>emptyList());
70
        this(Collections.<HudsonInstance>emptyList());
71
    }
71
    }
72
72
73
    public @Override Action createContextAwareInstance(Lookup actionContext) {
73
    public @Override Action createContextAwareInstance(Lookup actionContext) {
74
        return new PersistInstanceAction(actionContext.lookupAll(HudsonInstanceImpl.class));
74
        return new PersistInstanceAction(actionContext.lookupAll(HudsonInstance.class));
75
    }
75
    }
76
76
77
    private final Collection<? extends HudsonInstanceImpl> instances;
77
    private final Collection<? extends HudsonInstance> instances;
78
78
79
    private PersistInstanceAction(Collection<? extends HudsonInstanceImpl> instances) {
79
    private PersistInstanceAction(Collection<? extends HudsonInstance> instances) {
80
        super(LBL_Persist_Instance());
80
        super(LBL_Persist_Instance());
81
        this.instances = instances;
81
        this.instances = instances;
82
        for (HudsonInstanceImpl instance : instances) {
82
        for (HudsonInstance instance : instances) {
83
            if (instance.isPersisted()) {
83
            if (instance.isPersisted()) {
84
                setEnabled(false);
84
                setEnabled(false);
85
                break;
85
                break;
Lines 88-95 Link Here
88
    }
88
    }
89
89
90
    public @Override void actionPerformed(ActionEvent e) {
90
    public @Override void actionPerformed(ActionEvent e) {
91
        for (HudsonInstanceImpl instance : instances) {
91
        for (HudsonInstance instance : instances) {
92
            instance.makePersistent();
92
            Utilities.persistInstance(instance);
93
        }
93
        }
94
    }
94
    }
95
95
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/ProjectAssociationAction.java (-8 / +7 lines)
Lines 49-58 Link Here
49
import org.netbeans.api.project.ProjectUtils;
49
import org.netbeans.api.project.ProjectUtils;
50
import org.netbeans.api.project.ui.OpenProjects;
50
import org.netbeans.api.project.ui.OpenProjects;
51
import org.netbeans.modules.hudson.api.HudsonJob;
51
import org.netbeans.modules.hudson.api.HudsonJob;
52
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
52
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
53
import org.openide.DialogDisplayer;
53
import org.openide.DialogDisplayer;
54
import org.openide.NotifyDescriptor;
54
import org.openide.NotifyDescriptor;
55
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
56
import org.openide.util.NbBundle.Messages;
55
import org.openide.util.NbBundle.Messages;
57
56
58
/**
57
/**
Lines 71-79 Link Here
71
        assoc = ProjectHudsonProvider.Association.forJob(job);
70
        assoc = ProjectHudsonProvider.Association.forJob(job);
72
        this.alreadyAssociatedProject = ProjectHudsonProvider.getDefault().findAssociatedProject(assoc);
71
        this.alreadyAssociatedProject = ProjectHudsonProvider.getDefault().findAssociatedProject(assoc);
73
        if (alreadyAssociatedProject == null) {
72
        if (alreadyAssociatedProject == null) {
74
            putValue(NAME, ProjectAssociationAction_associate());
73
            putValue(NAME, Bundle.ProjectAssociationAction_associate());
75
        } else {
74
        } else {
76
            putValue(NAME, ProjectAssociationAction_dissociate(ProjectUtils.getInformation(alreadyAssociatedProject).getDisplayName()));
75
            putValue(NAME, Bundle.ProjectAssociationAction_dissociate(ProjectUtils.getInformation(alreadyAssociatedProject).getDisplayName()));
77
        }
76
        }
78
    }
77
    }
79
78
Lines 88-107 Link Here
88
            SortedSet<Project> projects = new TreeSet<Project>(ProjectRenderer.comparator());
87
            SortedSet<Project> projects = new TreeSet<Project>(ProjectRenderer.comparator());
89
            projects.addAll(Arrays.asList(OpenProjects.getDefault().getOpenProjects()));
88
            projects.addAll(Arrays.asList(OpenProjects.getDefault().getOpenProjects()));
90
            if (projects.isEmpty()) {
89
            if (projects.isEmpty()) {
91
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(ProjectAssociationAction_open_some_projects(), NotifyDescriptor.INFORMATION_MESSAGE));
90
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(Bundle.ProjectAssociationAction_open_some_projects(), NotifyDescriptor.INFORMATION_MESSAGE));
92
                return;
91
                return;
93
            }
92
            }
94
            JComboBox box = new JComboBox(new DefaultComboBoxModel(projects.toArray(new Project[projects.size()])));
93
            JComboBox box = new JComboBox(new DefaultComboBoxModel(projects.toArray(new Project[projects.size()])));
95
            box.setRenderer(new ProjectRenderer());
94
            box.setRenderer(new ProjectRenderer());
96
            if (DialogDisplayer.getDefault().notify(new NotifyDescriptor(box, ProjectAssociationAction_title_select_project(), NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.PLAIN_MESSAGE, null, null)) != NotifyDescriptor.OK_OPTION) {
95
            if (DialogDisplayer.getDefault().notify(new NotifyDescriptor(box, Bundle.ProjectAssociationAction_title_select_project(), NotifyDescriptor.OK_CANCEL_OPTION, NotifyDescriptor.PLAIN_MESSAGE, null, null)) != NotifyDescriptor.OK_OPTION) {
97
                return;
96
                return;
98
            }
97
            }
99
            if (!ProjectHudsonProvider.getDefault().recordAssociation((Project) box.getSelectedItem(), assoc)) {
98
            if (!ProjectHudsonProvider.getDefault().recordAssociation((Project) box.getSelectedItem(), assoc)) {
100
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(ProjectAssociationAction_could_not_associate(), NotifyDescriptor.WARNING_MESSAGE));
99
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(Bundle.ProjectAssociationAction_could_not_associate(), NotifyDescriptor.WARNING_MESSAGE));
101
            }
100
            }
102
        } else {
101
        } else {
103
            if (!ProjectHudsonProvider.getDefault().recordAssociation(alreadyAssociatedProject, null)) {
102
            if (!ProjectHudsonProvider.getDefault().recordAssociation(alreadyAssociatedProject, null)) {
104
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(ProjectAssociationAction_could_not_dissociate(), NotifyDescriptor.WARNING_MESSAGE));
103
                DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(Bundle.ProjectAssociationAction_could_not_dissociate(), NotifyDescriptor.WARNING_MESSAGE));
105
            }
104
            }
106
        }
105
        }
107
    }
106
    }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/ShowBuildConsole.java (-18 / +7 lines)
Lines 43-53 Link Here
43
43
44
import java.awt.event.ActionEvent;
44
import java.awt.event.ActionEvent;
45
import javax.swing.AbstractAction;
45
import javax.swing.AbstractAction;
46
import org.netbeans.modules.hudson.api.HudsonInstance;
47
import org.netbeans.modules.hudson.api.HudsonJobBuild;
46
import org.netbeans.modules.hudson.api.HudsonJobBuild;
48
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
47
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
49
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
48
import org.netbeans.modules.hudson.ui.impl.HudsonConsoleDisplayer;
50
import org.netbeans.modules.hudson.spi.BuilderConnector;
51
import org.openide.util.NbBundle.Messages;
49
import org.openide.util.NbBundle.Messages;
52
50
53
/**
51
/**
Lines 76-101 Link Here
76
74
77
    @Override
75
    @Override
78
    public void actionPerformed(ActionEvent e) {
76
    public void actionPerformed(ActionEvent e) {
79
        HudsonInstance instance = build.getJob().getInstance();
77
        if (moduleBuild != null) {
80
        if (instance instanceof HudsonInstanceImpl) {
78
            if (moduleBuild.canShowConsole()) {
81
            BuilderConnector builderClient =
79
                moduleBuild.showConsole(new HudsonConsoleDisplayer(moduleBuild));
82
                    ((HudsonInstanceImpl) instance).getBuilderConnector();
83
            if (moduleBuild != null) {
84
                builderClient.getConsoleDisplayer().showConsole(moduleBuild);
85
            } else {
86
                builderClient.getConsoleDisplayer().showConsole(build);
87
            }
80
            }
81
        } else if (build.canShowConsole()) {
82
            build.showConsole(new HudsonConsoleDisplayer(build));
88
        }
83
        }
89
    }
84
    }
90
85
91
    @Override
86
    @Override
92
    public boolean isEnabled() {
87
    public boolean isEnabled() {
93
        HudsonInstance instance = build.getJob().getInstance();
88
        return build.canShowConsole();
94
        if (instance instanceof HudsonInstanceImpl) {
95
            BuilderConnector builderClient =
96
                    ((HudsonInstanceImpl) instance).getBuilderConnector();
97
            return builderClient.getConsoleDisplayer() != null;
98
        }
99
        return false;
100
    }
89
    }
101
}
90
}
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/ShowFailures.java (-41 / +26 lines)
Lines 49-59 Link Here
49
import java.util.Set;
49
import java.util.Set;
50
import javax.swing.AbstractAction;
50
import javax.swing.AbstractAction;
51
import javax.swing.Action;
51
import javax.swing.Action;
52
import org.netbeans.modules.hudson.api.HudsonInstance;
53
import org.netbeans.modules.hudson.api.HudsonJobBuild;
52
import org.netbeans.modules.hudson.api.HudsonJobBuild;
54
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
53
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
55
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
54
import org.netbeans.modules.hudson.ui.impl.HudsonFailureDisplayer;
56
import org.netbeans.modules.hudson.spi.BuilderConnector;
57
import org.openide.util.ContextAwareAction;
55
import org.openide.util.ContextAwareAction;
58
import org.openide.util.Lookup;
56
import org.openide.util.Lookup;
59
import org.openide.util.NbBundle.Messages;
57
import org.openide.util.NbBundle.Messages;
Lines 93-119 Link Here
93
     */
91
     */
94
    private boolean canShowFailures(HudsonJobBuild build,
92
    private boolean canShowFailures(HudsonJobBuild build,
95
            HudsonMavenModuleBuild module) {
93
            HudsonMavenModuleBuild module) {
96
        HudsonInstance instance = build.getJob().getInstance();
94
97
        if (instance instanceof HudsonInstanceImpl) {
95
        if (module == null && !HudsonJobBuild.Result.UNSTABLE.equals(
98
            if (module == null && !HudsonJobBuild.Result.UNSTABLE.equals(
96
                build.getResult())) {
99
                    build.getResult())) {
97
            return false;
98
        } else if (module != null) {
99
            boolean failed = false;
100
            switch (module.getColor()) {
101
                case yellow:
102
                case yellow_anime:
103
                    failed = true;
104
            }
105
            if (!failed) {
100
                return false;
106
                return false;
101
            } else if (module != null) {
102
                boolean failed = false;
103
                switch (module.getColor()) {
104
                    case yellow:
105
                    case yellow_anime:
106
                        failed = true;
107
                }
108
                if (!failed) {
109
                    return false;
110
                }
111
            }
107
            }
112
            BuilderConnector builderClient =
113
                    ((HudsonInstanceImpl) instance).getBuilderConnector();
114
            return builderClient.getFailureDisplayer() != null;
115
        }
108
        }
116
        return false;
109
        return build.canShowFailures();
117
    }
110
    }
118
111
119
    /**
112
    /**
Lines 183-208 Link Here
183
        if (!canShowFailures(build, moduleBuild)) {
176
        if (!canShowFailures(build, moduleBuild)) {
184
            return;
177
            return;
185
        }
178
        }
186
        HudsonInstance hudsonInstance = build.getJob().getInstance();
179
        if (moduleBuild != null) {
187
        if (hudsonInstance instanceof HudsonInstanceImpl) {
180
            if (moduleBuild.canShowFailures()) {
188
            HudsonInstanceImpl hudsonInstanceImpl =
181
                moduleBuild.showFailures(new HudsonFailureDisplayer(moduleBuild));
189
                    (HudsonInstanceImpl) hudsonInstance;
182
            }
190
            BuilderConnector builderClient =
183
        } else if (build.canShowFailures()) {
191
                    hudsonInstanceImpl.getBuilderConnector();
184
            if (build.getMavenModules().isEmpty()) {
192
            BuilderConnector.FailureDisplayer failureDisplayer =
185
                build.showFailures(new HudsonFailureDisplayer(build));
193
                    builderClient.getFailureDisplayer();
186
            } else {
194
            if (failureDisplayer != null) {
187
                for (HudsonMavenModuleBuild extraModule
195
                if (moduleBuild != null) {
188
                        : getExtraModuleBuilds(build)) {
196
                    failureDisplayer.showFailures(moduleBuild);
189
                    extraModule.showFailures(
197
                } else {
190
                            new HudsonFailureDisplayer(extraModule));
198
                    if (build.getMavenModules().isEmpty()) {
199
                        failureDisplayer.showFailures(build);
200
                    } else {
201
                        for (HudsonMavenModuleBuild extraModule
202
                                : getExtraModuleBuilds(build)) {
203
                            failureDisplayer.showFailures(extraModule);
204
                        }
205
                    }
206
                }
191
                }
207
            }
192
            }
208
        }
193
        }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/SynchronizeAction.java (-7 / +6 lines)
Lines 50-56 Link Here
50
import javax.swing.AbstractAction;
50
import javax.swing.AbstractAction;
51
import javax.swing.Action;
51
import javax.swing.Action;
52
import org.netbeans.modules.hudson.api.HudsonInstance;
52
import org.netbeans.modules.hudson.api.HudsonInstance;
53
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
54
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
53
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
55
import org.openide.awt.ActionID;
54
import org.openide.awt.ActionID;
56
import org.openide.awt.ActionReference;
55
import org.openide.awt.ActionReference;
Lines 66-87 Link Here
66
@Messages("LBL_SynchronizeAction=&Synchronize")
65
@Messages("LBL_SynchronizeAction=&Synchronize")
67
public class SynchronizeAction extends AbstractAction implements ContextAwareAction {
66
public class SynchronizeAction extends AbstractAction implements ContextAwareAction {
68
67
69
    private final Collection<? extends HudsonInstanceImpl> instances;
68
    private final Collection<? extends HudsonInstance> instances;
70
69
71
    public SynchronizeAction() {
70
    public SynchronizeAction() {
72
        this(Collections.<HudsonInstanceImpl>emptySet());
71
        this(Collections.<HudsonInstance>emptySet());
73
    }
72
    }
74
73
75
    @Override public Action createContextAwareInstance(Lookup actionContext) {
74
    @Override public Action createContextAwareInstance(Lookup actionContext) {
76
        return new SynchronizeAction(actionContext.lookupAll(HudsonInstanceImpl.class));
75
        return new SynchronizeAction(actionContext.lookupAll(HudsonInstance.class));
77
    }
76
    }
78
77
79
    @Messages("LBL_SynchronizeAction_disconnected=Connect")
78
    @Messages("LBL_SynchronizeAction_disconnected=Connect")
80
    private SynchronizeAction(Collection<? extends HudsonInstanceImpl> instances) {
79
    private SynchronizeAction(Collection<? extends HudsonInstance> instances) {
81
        this.instances = instances;
80
        this.instances = instances;
82
        boolean allForbidden = true;
81
        boolean allForbidden = true;
83
        boolean allDisconnected = true;
82
        boolean allDisconnected = true;
84
        for (HudsonInstanceImpl instance : instances) {
83
        for (HudsonInstance instance : instances) {
85
            if (!instance.isForbidden()) {
84
            if (!instance.isForbidden()) {
86
                allForbidden = false;
85
                allForbidden = false;
87
            }
86
            }
Lines 101-107 Link Here
101
    }
100
    }
102
    
101
    
103
    public @Override void actionPerformed(ActionEvent e) {
102
    public @Override void actionPerformed(ActionEvent e) {
104
        for (HudsonInstanceImpl instance : instances) {
103
        for (HudsonInstance instance : instances) {
105
            instance.synchronize(true);
104
            instance.synchronize(true);
106
        }
105
        }
107
    }
106
    }
(-)a/hudson.ui/src/org/netbeans/modules/hudson/ui/api/HudsonSCMHelper.java (+132 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
43
package org.netbeans.modules.hudson.ui.api;
44
45
import java.awt.BorderLayout;
46
import java.awt.EventQueue;
47
import java.io.IOException;
48
import java.util.logging.Level;
49
import java.util.logging.Logger;
50
import org.netbeans.api.diff.Diff;
51
import org.netbeans.api.diff.DiffView;
52
import org.netbeans.api.diff.StreamSource;
53
import org.netbeans.modules.hudson.api.Utilities;
54
import org.netbeans.modules.hudson.spi.HudsonSCM;
55
import org.openide.awt.StatusDisplayer;
56
import org.openide.util.NbBundle;
57
import org.openide.windows.TopComponent;
58
import org.w3c.dom.Document;
59
import org.w3c.dom.Element;
60
61
/**
62
 * Convenience methods for SCM implementations.
63
 */
64
public class HudsonSCMHelper {
65
    private static final Logger LOG = Logger.getLogger(HudsonSCM.class.getName());
66
67
        private HudsonSCMHelper() {}
68
69
        /**
70
         * Add an SCM polling trigger.
71
         * @param configXml a {@code config.xml}
72
         */
73
        public static void addTrigger(Document configXml) {
74
            Element root = configXml.getDocumentElement();
75
            root.appendChild(configXml.createElement("triggers")). // NOI18N // XXX reuse existing <triggers> if found
76
                    appendChild(configXml.createElement("hudson.triggers.SCMTrigger")). // NOI18N
77
                    appendChild(configXml.createElement("spec")). // NOI18N
78
                    // XXX pretty arbitrary but seems like a decent first guess
79
                    appendChild(configXml.createTextNode("@hourly")); // NOI18N
80
        }
81
82
        @Deprecated
83
        public static String xpath(String expr, Element xml) {
84
            return Utilities.xpath(expr, xml);
85
        }
86
87
        /**
88
         * Just notify the user that a diff will be shown for a given path.
89
         * @param path a path, probably somehow repo-relative
90
         */
91
        @NbBundle.Messages({"# {0} - portion of file path", "HudsonSCM.loading_diff=Loading diff for {0}..."})
92
        public static void noteWillShowDiff(String path) {
93
            StatusDisplayer.getDefault().setStatusText(Bundle.HudsonSCM_loading_diff(path));
94
        }
95
96
        /**
97
         * Display a diff window for a file.
98
         * @param before the former contents
99
         * @param after the new contents
100
         * @param path some representation of the file path
101
         */
102
        @NbBundle.Messages({"# {0} - file basename", "HudsonSCM.diffing=Diffing {0}"})
103
        public static void showDiff(final StreamSource before, final StreamSource after, final String path) {
104
            EventQueue.invokeLater(new Runnable() {
105
                @Override public void run() {
106
                    try {
107
                        DiffView view = Diff.getDefault().createDiff(before, after);
108
                        // XXX reuse the same TC
109
                        DiffTopComponent tc = new DiffTopComponent(view);
110
                        tc.setName(path);
111
                        tc.setDisplayName(Bundle.HudsonSCM_diffing(path.replaceFirst(".+/", ""))); //NOI18N
112
                        tc.open();
113
                        tc.requestActive();
114
                    } catch (IOException x) {
115
                        LOG.log(Level.INFO, null, x);
116
                    }
117
                }
118
            });
119
        }
120
        private static class DiffTopComponent extends TopComponent {
121
            DiffTopComponent(DiffView view) {
122
                setLayout(new BorderLayout());
123
                add(view.getComponent(), BorderLayout.CENTER);
124
            }
125
            public @Override int getPersistenceType() {
126
                return TopComponent.PERSISTENCE_NEVER;
127
            }
128
            protected @Override String preferredID() {
129
                return "DiffTopComponent"; // NOI18N
130
            }
131
        }
132
}
(-)a/hudson/src/org/netbeans/modules/hudson/api/UI.java (-3 / +6 lines)
Lines 40-53 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.api;
43
package org.netbeans.modules.hudson.ui.api;
44
44
45
import java.beans.PropertyVetoException;
45
import java.beans.PropertyVetoException;
46
import java.util.logging.Level;
46
import java.util.logging.Level;
47
import java.util.logging.Logger;
47
import java.util.logging.Logger;
48
import javax.swing.Action;
48
import javax.swing.Action;
49
import javax.swing.Icon;
49
import javax.swing.Icon;
50
import org.netbeans.modules.hudson.impl.HudsonJobBuildImpl;
50
import org.netbeans.modules.hudson.api.HudsonJob;
51
import org.netbeans.modules.hudson.api.HudsonJobBuild;
52
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
53
import org.netbeans.modules.hudson.api.Utilities;
51
import org.netbeans.modules.hudson.ui.actions.ShowBuildConsole;
54
import org.netbeans.modules.hudson.ui.actions.ShowBuildConsole;
52
import org.netbeans.modules.hudson.ui.actions.ShowChanges;
55
import org.netbeans.modules.hudson.ui.actions.ShowChanges;
53
import org.netbeans.modules.hudson.ui.actions.ShowFailures;
56
import org.netbeans.modules.hudson.ui.actions.ShowFailures;
Lines 162-168 Link Here
162
     * Return icon for a Hudson Job build.
165
     * Return icon for a Hudson Job build.
163
     */
166
     */
164
    public static Icon getIcon(HudsonJobBuild build) {
167
    public static Icon getIcon(HudsonJobBuild build) {
165
        return makeIcon(HudsonJobBuildImpl.getColorForBuild(build).iconBase());
168
        return makeIcon(Utilities.getColorForBuild(build).iconBase());
166
    }
169
    }
167
170
168
    private static Icon makeIcon(String iconBase) {
171
    private static Icon makeIcon(String iconBase) {
(-)a/hudson.ui/src/org/netbeans/modules/hudson/ui/impl/HudsonConsoleDisplayer.java (+102 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
43
package org.netbeans.modules.hudson.ui.impl;
44
45
import javax.swing.Action;
46
import org.netbeans.modules.hudson.api.HudsonJob;
47
import org.netbeans.modules.hudson.api.HudsonJobBuild;
48
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
49
import org.netbeans.modules.hudson.spi.ConsoleDataDisplayerImpl;
50
import org.netbeans.modules.hudson.ui.actions.Hyperlinker;
51
import org.openide.windows.IOProvider;
52
import org.openide.windows.InputOutput;
53
import org.openide.windows.OutputWriter;
54
55
/**
56
 *
57
 * @author jhavlin
58
 */
59
public class HudsonConsoleDisplayer extends ConsoleDataDisplayerImpl {
60
61
    private final HudsonJob job;
62
    private final String displayName;
63
    private OutputWriter out;
64
    private OutputWriter err;
65
    private Hyperlinker hyperlinker;
66
    private InputOutput io;
67
68
    public HudsonConsoleDisplayer(HudsonJobBuild build) {
69
        this.job = build.getJob();
70
        this.displayName = build.getDisplayName();
71
    }
72
73
    public HudsonConsoleDisplayer(HudsonMavenModuleBuild moduleBuild) {
74
        this.job = moduleBuild.getBuild().getJob();
75
        this.displayName = moduleBuild.getDisplayName();
76
    }
77
78
    @Override
79
    public synchronized void open() {
80
        hyperlinker = new Hyperlinker(job);
81
        io = IOProvider.getDefault().getIO(displayName, new Action[]{});
82
        io.select();
83
        out = io.getOut();
84
        err = io.getErr();
85
    }
86
87
    @Override
88
    public synchronized boolean writeLine(String line) {
89
        if (out.checkError() || err.checkError() || io.isClosed()) {
90
            return false;
91
        }
92
        OutputWriter stream = line.matches("(?i).*((warn(ing)?|err(or)?)[]:]|failed).*") ? err : out; //NOI18N
93
        hyperlinker.handleLine(line, stream);
94
        return true;
95
    }
96
97
    @Override
98
    public void close() {
99
        out.close();
100
        err.close();
101
    }
102
}
(-)a/hudson.ui/src/org/netbeans/modules/hudson/ui/impl/HudsonFailureDisplayer.java (+307 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
43
package org.netbeans.modules.hudson.ui.impl;
44
45
import java.awt.event.ActionEvent;
46
import java.util.logging.Level;
47
import java.util.logging.Logger;
48
import java.util.regex.Matcher;
49
import java.util.regex.Pattern;
50
import javax.swing.AbstractAction;
51
import javax.swing.Action;
52
import org.netbeans.api.java.classpath.GlobalPathRegistry;
53
import org.netbeans.api.project.Project;
54
import org.netbeans.modules.gsf.testrunner.api.CallstackFrameNode;
55
import org.netbeans.modules.gsf.testrunner.api.DiffViewAction;
56
import org.netbeans.modules.gsf.testrunner.api.Manager;
57
import org.netbeans.modules.gsf.testrunner.api.TestMethodNode;
58
import org.netbeans.modules.gsf.testrunner.api.TestRunnerNodeFactory;
59
import org.netbeans.modules.gsf.testrunner.api.TestSession;
60
import org.netbeans.modules.gsf.testrunner.api.TestSuite;
61
import org.netbeans.modules.gsf.testrunner.api.Testcase;
62
import org.netbeans.modules.gsf.testrunner.api.TestsuiteNode;
63
import org.netbeans.modules.gsf.testrunner.api.Trouble;
64
import org.netbeans.modules.hudson.api.HudsonJob;
65
import org.netbeans.modules.hudson.api.HudsonJobBuild;
66
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
67
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer;
68
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
69
import org.netbeans.modules.hudson.spi.FailureDataDisplayerImpl;
70
import org.netbeans.modules.hudson.ui.actions.Hyperlinker;
71
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
72
import org.openide.awt.StatusDisplayer;
73
import org.openide.filesystems.FileObject;
74
import org.openide.filesystems.FileUtil;
75
import org.openide.util.Lookup;
76
import org.openide.util.NbBundle;
77
import org.openide.util.RequestProcessor;
78
import org.openide.windows.IOProvider;
79
import org.openide.windows.InputOutput;
80
import org.openide.windows.OutputWriter;
81
82
/**
83
 *
84
 * @author jhavlin
85
 */
86
@NbBundle.Messages({
87
    "# {0} - job #build", "ShowFailures.title={0} Test Failures",
88
    "# {0} - class & method name of failed test", "# {1} - suite name of failed test", "ShowFailures.from_suite={0} (from {1})",
89
    "LBL_GotoSource=Go to Source",
90
    "# {0} - Java source file resource path", "no_source_to_hyperlink=Could not find {0} among open projects."
91
})
92
public class HudsonFailureDisplayer extends FailureDataDisplayerImpl {
93
94
    private static final RequestProcessor RP = new RequestProcessor(
95
            HudsonFailureDisplayer.class.getName());
96
    private static final Logger LOG = Logger.getLogger(
97
            HudsonFailureDisplayer.class.getName());
98
    private static final Pattern ASSERTION_FAILURE = Pattern.compile(
99
            "(?m)junit[.]framework[.](AssertionFailedError|(Array)?ComparisonFailure)|java[.]lang[.]AssertionError($|: )"); //NOI18N
100
101
    private final Project project;
102
    private final TestSession session;
103
    private final Hyperlinker hyperlinker;
104
    private InputOutput io;
105
106
    private final HudsonJob job;
107
    private final HudsonJobBuild build;
108
    private final String displayName;
109
110
    public HudsonFailureDisplayer(HudsonJobBuild build) {
111
        this(build, build.getDisplayName());
112
    }
113
114
    public HudsonFailureDisplayer(HudsonMavenModuleBuild moduleBuild) {
115
        this(moduleBuild.getBuild(), moduleBuild.getDisplayName());
116
    }
117
118
    private HudsonFailureDisplayer(HudsonJobBuild build,
119
            String displayName) {
120
        this.build = build;
121
        this.job = this.build.getJob();
122
        this.displayName = displayName;
123
        this.hyperlinker = new Hyperlinker(job);
124
        // Store reference to project here, as reference in test session
125
        // is weak.
126
        this.project = createDummyProject();
127
        this.session = createTestSession(displayName);
128
    }
129
130
    private Project createDummyProject() {
131
        return new Project() {
132
            public @Override
133
            FileObject getProjectDirectory() {
134
                return FileUtil.createMemoryFileSystem().getRoot();
135
            }
136
137
            public @Override
138
            Lookup getLookup() {
139
                return Lookup.EMPTY;
140
            }
141
        };
142
    }
143
144
    private TestSession createTestSession(String displayName) {
145
146
        TestRunnerNodeFactory testRunnerNodeFactory
147
                = new HudsonTestRunnerNodeFactory();
148
        return new TestSession(displayName, project,
149
                TestSession.SessionType.TEST, testRunnerNodeFactory);
150
    }
151
152
    private void prepareOutput() {
153
        if (io == null) {
154
            String title = Bundle.ShowFailures_title(displayName);
155
            io = IOProvider.getDefault().getIO(title, new Action[0]);
156
            io.select();
157
            Manager.getInstance().testStarted(session);
158
        }
159
    }
160
161
    @Override
162
    public void open() {
163
    }
164
165
    @Override
166
    public void showSuite(FailureDataDisplayer.Suite s) {
167
168
        prepareOutput();
169
        OutputWriter out = io.getOut();
170
        OutputWriter err = io.getErr();
171
        TestSuite suite = new TestSuite(s.getName());
172
        session.addSuite(suite);
173
        Manager.getInstance().displaySuiteRunning(session, suite.getName());
174
        if (s.getStderr() != null) {
175
            // XXX TR window does not seem to show only stdio from selected suite
176
            Manager.getInstance().displayOutput(session, s.getStderr(), true);
177
        }
178
        if (s.getStdout() != null) {
179
            Manager.getInstance().displayOutput(session, s.getStdout(), false);
180
        }
181
        for (final FailureDataDisplayer.Case c : s.getCases()) {
182
            if (c.getErrorStackTrace() == null) {
183
                continue;
184
            }
185
            String name = c.getClassName() + "." + c.getName(); //NOI18N
186
            String shortName = c.getName();
187
            if (s.getName() != null && !s.getName().equals(c.getClassName())) {
188
                shortName = name;
189
                name = Bundle.ShowFailures_from_suite(name, s.getName());
190
            }
191
            println();
192
            out.println("[" + name + "]"); // XXX use color printing to make it stand out? //NOI18N
193
            show(c.getErrorStackTrace(), /* err is too hard to read */ out);
194
            Testcase test = new Testcase(shortName, null, session);
195
            test.setClassName(c.getClassName());
196
            Trouble trouble = new Trouble(!ASSERTION_FAILURE.matcher(c.getErrorStackTrace()).lookingAt());
197
            trouble.setStackTrace(c.getErrorStackTrace().split("\r?\n")); //NOI18N
198
            // XXX call setComparisonFailure if matches "expected:<...> but was:<...>"
199
            test.setTrouble(trouble);
200
            LOG.log(Level.FINE, "got {0} as {1}", new Object[]{name, test.getStatus()}); //NOI18N
201
            test.setTimeMillis(c.getDuration());
202
            session.addTestCase(test);
203
        }
204
        if (s.getStderr() != null || s.getStdout() != null) {
205
            println();
206
            show(s.getStderr(), err);
207
            show(s.getStdout(), out);
208
        }
209
        Manager.getInstance().displayReport(session, session.getReport(s.getDuration()));
210
    }
211
    boolean firstLine = true;
212
213
    void println() {
214
        if (firstLine) {
215
            firstLine = false;
216
        } else {
217
            io.getOut().println();
218
        }
219
    }
220
221
    void show(String lines, OutputWriter w) {
222
        if (lines == null) {
223
            return;
224
        }
225
        for (String line : lines.split("\r\n?|\n")) { //NOI18N
226
            hyperlinker.handleLine(line, w);
227
        }
228
    }
229
230
    @Override
231
    public void close() {
232
        if (io != null) {
233
            io.getOut().close();
234
            io.getErr().close();
235
            Manager.getInstance().sessionFinished(session);
236
        }
237
    }
238
239
    private class HudsonTestRunnerNodeFactory extends TestRunnerNodeFactory {
240
241
        public HudsonTestRunnerNodeFactory() {
242
        }
243
244
        public @Override
245
        TestsuiteNode createTestSuiteNode(String suiteName, boolean filtered) {
246
            // XXX could add OpenableInBrowser
247
            return new TestsuiteNode(suiteName, filtered);
248
        }
249
250
        public @Override
251
        org.openide.nodes.Node createTestMethodNode(final Testcase testcase,
252
                Project project) {
253
            return new TestMethodNode(testcase, project) {
254
                public @Override
255
                Action[] getActions(boolean context) {
256
                    return new Action[]{
257
                        OpenUrlAction.forOpenable(new OpenableInBrowser() {
258
                            public @Override
259
                            String getUrl() {
260
                                return getUrl() + "testReport/"
261
                                        + testcase.getClassName().replaceFirst("[.][^.]+$", "") + "/" + testcase.getClassName().replaceFirst(".+[.]", "") + "/" + testcase.getName() + "/"; //NOI18N
262
                            }
263
                        }),
264
                        new DiffViewAction(testcase),};
265
                }
266
            };
267
        }
268
269
        public @Override
270
        org.openide.nodes.Node createCallstackFrameNode(String frameInfo, String displayName) {
271
            return new CallstackFrameNode(frameInfo, displayName) {
272
                public @Override
273
                Action getPreferredAction() {
274
                    return new AbstractAction(Bundle.LBL_GotoSource()) {
275
                        public @Override
276
                        void actionPerformed(ActionEvent e) {
277
                            // XXX should have utility API to parse stack traces
278
                            final Matcher m = Pattern.compile("\tat (.+[.])[^.]+[.][^.]+[(]([^.]+[.]java):([0-9]+)[)]").matcher(frameInfo); //NOI18N
279
                            if (m.matches()) {
280
                                final String resource = m.group(1).replace('.', '/') + m.group(2);
281
                                RP.post(new Runnable() {
282
                                    @Override
283
                                    public void run() {
284
                                        FileObject f = GlobalPathRegistry.getDefault().findResource(resource);
285
                                        LOG.log(Level.FINER, "matched {0} -> {1}", new Object[]{resource, f}); //NOI18N
286
                                        if (f != null) {
287
                                            HudsonLoggerHelper.openAt(f, Integer.parseInt(m.group(3)) - 1, -1, true);
288
                                        } else {
289
                                            StatusDisplayer.getDefault().setStatusText(Bundle.no_source_to_hyperlink(resource));
290
                                        }
291
                                    }
292
                                });
293
                            } else {
294
                                LOG.log(Level.FINER, "no match for {0}", frameInfo); //NOI18N
295
                            }
296
                        }
297
                    };
298
                }
299
300
                public @Override
301
                Action[] getActions(boolean context) {
302
                    return new Action[]{getPreferredAction()};
303
                }
304
            };
305
        }
306
    }
307
}
(-)a/hudson.ui/src/org/netbeans/modules/hudson/ui/impl/HudsonLoggerHelper.java (+129 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
43
package org.netbeans.modules.hudson.ui.impl;
44
45
import java.awt.EventQueue;
46
import java.io.IOException;
47
import java.util.logging.Level;
48
import java.util.logging.Logger;
49
import org.netbeans.modules.hudson.spi.HudsonLogger;
50
import org.openide.cookies.EditorCookie;
51
import org.openide.cookies.LineCookie;
52
import org.openide.cookies.OpenCookie;
53
import org.openide.filesystems.FileObject;
54
import org.openide.loaders.DataObject;
55
import org.openide.text.Line;
56
57
/**
58
 * Utilities for use by a logger.
59
 */
60
public class HudsonLoggerHelper {
61
62
    private static final Logger LOG = Logger.getLogger(HudsonLogger.class.getName());
63
64
    /**
65
     * Try to open a file, possibly at a given position.
66
     *
67
     * @param f a file to open
68
     * @param row the row number (zero-based), or -1 for none
69
     * @param col the column number (zero-based), or -1 for none
70
     * @param force true to forcibly open the file, false to just scroll if
71
     * already open
72
     */
73
    public static void openAt(FileObject f, int row, final int col, final boolean force) {
74
        try {
75
            DataObject d = DataObject.find(f);
76
            if (row == -1) {
77
                if (force) {
78
                    Runnable r;
79
                    final EditorCookie c = d.getLookup().lookup(EditorCookie.class);
80
                    if (c != null) {
81
                        r = new Runnable() {
82
                            public void run() {
83
                                try {
84
                                    c.openDocument();
85
                                } catch (IOException x) {
86
                                    LOG.log(Level.INFO, null, x);
87
                                }
88
                            }
89
                        };
90
                    } else {
91
                        LOG.fine("no EditorCookie found for " + f);
92
                        final OpenCookie o = d.getLookup().lookup(OpenCookie.class);
93
                        if (o == null) {
94
                            LOG.fine("no OpenCookie found for " + f);
95
                            return;
96
                        }
97
                        r = new Runnable() {
98
                            public void run() {
99
                                o.open();
100
                            }
101
                        };
102
                    }
103
                    EventQueue.invokeLater(r);
104
                }
105
                return;
106
            }
107
            LineCookie c = d.getLookup().lookup(LineCookie.class);
108
            if (c == null) {
109
                LOG.fine("no LineCookie found for " + f);
110
                openAt(f, -1, -1, force);
111
                return;
112
            }
113
            try {
114
                final Line l = c.getLineSet().getOriginal(row);
115
                EventQueue.invokeLater(new Runnable() {
116
                    public void run() {
117
                        l.show(force ? Line.ShowOpenType.REUSE : Line.ShowOpenType.NONE,
118
                                force ? Line.ShowVisibilityType.FOCUS : Line.ShowVisibilityType.FRONT, col);
119
                    }
120
                });
121
            } catch (IndexOutOfBoundsException x) {
122
                LOG.log(Level.INFO, null, x);
123
            }
124
        } catch (IOException x) {
125
            LOG.log(Level.INFO, null, x);
126
        }
127
    }
128
129
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/JavaHudsonLogger.java (-2 / +2 lines)
Lines 40-46 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.impl;
43
package org.netbeans.modules.hudson.ui.impl;
44
44
45
import java.awt.Toolkit;
45
import java.awt.Toolkit;
46
import java.io.IOException;
46
import java.io.IOException;
Lines 128-134 Link Here
128
                    if (source != null) {
128
                    if (source != null) {
129
                        // XXX possible to also display exception message in status line
129
                        // XXX possible to also display exception message in status line
130
                        // (would need to have grepped output for EXCEPTION_MESSAGE)
130
                        // (would need to have grepped output for EXCEPTION_MESSAGE)
131
                        Helper.openAt(source, lineNumber - 1, -1, force);
131
                        HudsonLoggerHelper.openAt(source, lineNumber - 1, -1, force);
132
                    } else if (force) {
132
                    } else if (force) {
133
                        Toolkit.getDefaultToolkit().beep();
133
                        Toolkit.getDefaultToolkit().beep();
134
                    }
134
                    }
(-)a/hudson/src/org/netbeans/modules/hudson/impl/MetadataProjectHudsonProvider.java (-2 / +2 lines)
Lines 40-51 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.impl;
43
package org.netbeans.modules.hudson.ui.impl;
44
44
45
import java.util.prefs.Preferences;
45
import java.util.prefs.Preferences;
46
import org.netbeans.api.project.Project;
46
import org.netbeans.api.project.Project;
47
import org.netbeans.api.project.ProjectUtils;
47
import org.netbeans.api.project.ProjectUtils;
48
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
48
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
49
import org.openide.util.lookup.ServiceProvider;
49
import org.openide.util.lookup.ServiceProvider;
50
50
51
/**
51
/**
(-)a/hudson.ui/src/org/netbeans/modules/hudson/ui/impl/OpenProjectstHudsonManagerAgent.java (+244 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
43
package org.netbeans.modules.hudson.ui.impl;
44
45
import java.beans.PropertyChangeEvent;
46
import java.beans.PropertyChangeListener;
47
import java.util.ArrayList;
48
import java.util.Arrays;
49
import java.util.HashMap;
50
import java.util.List;
51
import java.util.Map;
52
import java.util.concurrent.ExecutionException;
53
import java.util.concurrent.Future;
54
import org.netbeans.api.project.Project;
55
import org.netbeans.api.project.ui.OpenProjects;
56
import org.netbeans.modules.hudson.api.HudsonChangeAdapter;
57
import org.netbeans.modules.hudson.api.HudsonInstance;
58
import org.netbeans.modules.hudson.api.HudsonManager;
59
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
60
import org.netbeans.modules.hudson.spi.HudsonManagerAgent;
61
import org.netbeans.modules.hudson.ui.notification.ProblemNotificationController;
62
import org.openide.util.Exceptions;
63
import org.openide.util.RequestProcessor;
64
import org.openide.util.lookup.ServiceProvider;
65
66
/**
67
 *
68
 * @author jhavlin
69
 */
70
@ServiceProvider(service = HudsonManagerAgent.class)
71
public class OpenProjectstHudsonManagerAgent extends HudsonManagerAgent {
72
73
    private static final RequestProcessor RP
74
            = new RequestProcessor(OpenProjectstHudsonManagerAgent.class);
75
    private final PropertyChangeListener projectsListener;
76
    private final Map<Project, HudsonInstance> projectInstances
77
            = new HashMap<Project, HudsonInstance>();
78
    private final Map<HudsonInstance, ProblemNotificationController> notifications
79
            = new HashMap<HudsonInstance, ProblemNotificationController>();
80
81
    /**
82
     * Mapping from Hudson instance to one or more providers (projects).
83
     */
84
    private final Map<HudsonInstance, List<Project>> instanceProviders
85
            = new HashMap<HudsonInstance, List<Project>>();
86
    private final RequestProcessor.Task checkOpenProjects = RP.create(new Runnable() {
87
        public @Override
88
        void run() {
89
            checkOpenProjects();
90
        }
91
    });
92
93
    public OpenProjectstHudsonManagerAgent() {
94
        projectsListener = new PropertyChangeListener() {
95
            @Override
96
            public void propertyChange(PropertyChangeEvent evt) {
97
                if (OpenProjects.PROPERTY_OPEN_PROJECTS.equals(
98
                        evt.getPropertyName())) {
99
                    checkOpenProjects.schedule(0);
100
                }
101
            }
102
        };
103
    }
104
105
    @Override
106
    public void start() {
107
        OpenProjects.getDefault().addPropertyChangeListener(projectsListener);
108
        checkOpenProjects.schedule(0);
109
    }
110
111
    @Override
112
    public void terminate() {
113
        OpenProjects.getDefault().removePropertyChangeListener(projectsListener);
114
        projectInstances.clear();
115
    }
116
117
    private synchronized void checkOpenProjects() {
118
        try {
119
            Future<Project[]> fut = OpenProjects.getDefault().openProjects();
120
            Project[] prjs = fut.get();
121
            for (Project project : prjs) {
122
                boolean exists = projectInstances.containsKey(project);
123
                ProjectHudsonProvider.Association assoc
124
                        = ProjectHudsonProvider.getDefault().findAssociation(project);
125
                if (assoc != null && !exists) {
126
                    String url = assoc.getServerUrl();
127
                    HudsonInstance in = HudsonManager.getInstance(url);
128
                    if (in == null) {
129
                        String n = HudsonManager.simplifyServerLocation(url, false);
130
                        in = HudsonManager.addInstance(n, url, 60, false);
131
                    }
132
                    addProvider(in, project);
133
                    projectInstances.put(project, in);
134
                } else if (assoc == null && exists) {
135
                    HudsonInstance remove = projectInstances.remove(project);
136
                    if (remove != null) {
137
                        removeProvider(remove, project);
138
                        if (!hasProvider(remove)) {
139
                            HudsonManager.removeInstance(remove);
140
                        }
141
                    }
142
                }
143
            }
144
            ArrayList<Project> newprjs = new ArrayList<Project>(projectInstances.keySet());
145
            newprjs.removeAll(Arrays.asList(prjs));
146
            for (Project project : newprjs) {
147
                HudsonInstance remove = projectInstances.remove(project);
148
                if (remove != null && hasProvider(remove)
149
                        && !remove.isPersisted()) {
150
                    removeProvider(remove, project);
151
                    if (!hasProvider(remove)) {
152
                        HudsonManager.removeInstance(remove);
153
                    }
154
                }
155
            }
156
        } catch (InterruptedException ex) {
157
            Exceptions.printStackTrace(ex);
158
        } catch (ExecutionException ex) {
159
            Exceptions.printStackTrace(ex);
160
        }
161
    }
162
163
    private void addProvider(HudsonInstance instance, Project project) {
164
        List<Project> providers = instanceProviders.get(instance);
165
        if (providers == null) {
166
            providers = new ArrayList<Project>();
167
            instanceProviders.put(instance, providers);
168
        }
169
        if (!providers.contains(project)) {
170
            providers.add(project);
171
        }
172
        setPreferredJobs(instance);
173
    }
174
175
    private void removeProvider(HudsonInstance instance, Project project) {
176
        List<Project> providers = instanceProviders.get(instance);
177
        if (providers != null) {
178
            providers.remove(project);
179
            if (providers.isEmpty()) {
180
                instanceProviders.remove(instance);
181
            }
182
        }
183
        setPreferredJobs(instance);
184
    }
185
186
    private boolean hasProvider(HudsonInstance instance) {
187
        List<Project> providers = instanceProviders.get(instance);
188
        if (providers == null) {
189
            return false;
190
        } else {
191
            if (providers.isEmpty()) {
192
                instanceProviders.remove(instance);
193
                return false;
194
            } else {
195
                return true;
196
            }
197
        }
198
    }
199
200
    private List<Project> getProviders(HudsonInstance instance) {
201
        return instanceProviders.get(instance);
202
    }
203
204
    private void setPreferredJobs(HudsonInstance instance) {
205
        List<Project> providers = getProviders(instance);
206
        if (providers == null) {
207
            return;
208
        }
209
        List<String> names = new ArrayList<String>();
210
        for (Project prj : providers) {
211
            ProjectHudsonProvider.Association assoc
212
                    = ProjectHudsonProvider.getDefault().findAssociation(prj);
213
            if (assoc != null) {
214
                String name = assoc.getJobName();
215
                if (name != null) {
216
                    names.add(name);
217
                }
218
            }
219
        }
220
        instance.setPreferredJobs(names);
221
    }
222
223
    @Override
224
    public void instanceAdded(HudsonInstance instance) {
225
        final ProblemNotificationController controller =
226
                new ProblemNotificationController(instance);
227
        instance.addHudsonChangeListener(new HudsonChangeAdapter() {
228
229
            @Override
230
            public void contentChanged() {
231
                controller.updateNotifications();
232
            }
233
        });
234
        notifications.put(instance, controller);
235
    }
236
237
    @Override
238
    public void instanceRemoved(HudsonInstance instance) {
239
        ProblemNotificationController c = notifications.remove(instance);
240
        if (c != null) {
241
            c.clearNotifications();
242
        }
243
    }
244
}
(-)a/hudson/src/org/netbeans/modules/hudson/ui/actions/Hyperlinker.java (-52 / +33 lines)
Lines 40-54 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.ui.actions;
43
package org.netbeans.modules.hudson.ui.impl;
44
44
45
import java.awt.Toolkit;
45
import java.awt.Toolkit;
46
import java.io.File;
46
import java.io.File;
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.net.MalformedURLException;
48
import java.net.MalformedURLException;
49
import java.net.URL;
49
import java.net.URL;
50
import java.util.ArrayList;
51
import java.util.List;
52
import java.util.logging.Level;
50
import java.util.logging.Level;
53
import java.util.logging.Logger;
51
import java.util.logging.Logger;
54
import java.util.regex.Matcher;
52
import java.util.regex.Matcher;
Lines 58-64 Link Here
58
import org.netbeans.modules.hudson.spi.HudsonLogger;
56
import org.netbeans.modules.hudson.spi.HudsonLogger;
59
import org.netbeans.modules.hudson.spi.HudsonLogger.HudsonLogSession;
57
import org.netbeans.modules.hudson.spi.HudsonLogger.HudsonLogSession;
60
import org.netbeans.modules.hudson.spi.HudsonSCM;
58
import org.netbeans.modules.hudson.spi.HudsonSCM;
61
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
59
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider;
62
import org.openide.awt.HtmlBrowser.URLDisplayer;
60
import org.openide.awt.HtmlBrowser.URLDisplayer;
63
import org.openide.awt.StatusDisplayer;
61
import org.openide.awt.StatusDisplayer;
64
import org.openide.filesystems.FileObject;
62
import org.openide.filesystems.FileObject;
Lines 70-102 Link Here
70
import org.openide.windows.OutputEvent;
68
import org.openide.windows.OutputEvent;
71
import org.openide.windows.OutputListener;
69
import org.openide.windows.OutputListener;
72
import org.openide.windows.OutputWriter;
70
import org.openide.windows.OutputWriter;
73
import static org.netbeans.modules.hudson.ui.actions.Bundle.*;
74
71
75
/**
72
@ServiceProvider(service=HudsonLogger.class, position = Integer.MAX_VALUE - 100)
76
 * Manages warning/error/stack trace hyperlinking in the Output Window.
73
public class PlainLogger implements HudsonLogger {
77
 */
78
public class Hyperlinker {
79
74
80
    private static final Logger LOG = Logger.getLogger(Hyperlinker.class.getName());
75
    private static final Logger LOG = Logger.getLogger(PlainLogger.class.getName());
81
76
82
    private final HudsonLogSession[] sessions;
77
    @Override
83
78
    public HudsonLogSession createSession(final HudsonJob job) {
84
    public Hyperlinker(HudsonJob job) {
79
            return new HudsonLogSession() {
85
        List<HudsonLogSession> _sessions = new ArrayList<HudsonLogSession>();
80
                final PlainLoggerLogic logic = new PlainLoggerLogic(job, job.getName());
86
        for (HudsonLogger logger : Lookup.getDefault().lookupAll(HudsonLogger.class)) {
81
                public boolean handle(String line, OutputWriter stream) {
87
            _sessions.add(logger.createSession(job));
82
                    OutputListener link = logic.findHyperlink(line);
83
                    if (link != null) {
84
                        try {
85
                            stream.println(line, link);
86
                            return true;
87
                        } catch (IOException x) {
88
                            LOG.log(Level.INFO, null, x);
89
                        }
90
                    }
91
                    stream.println(line);
92
                    return true;
93
                }
94
            };
88
        }
95
        }
89
        sessions = _sessions.toArray(new HudsonLogSession[_sessions.size()]);
90
    }
91
92
    public void handleLine(String line, OutputWriter stream) {
93
        for (HudsonLogSession session : sessions) {
94
            if (session.handle(line, stream)) {
95
                break;
96
            }
97
        }
98
        // PlainLogger is last and always handles it
99
    }
100
96
101
    static class PlainLoggerLogic {
97
    static class PlainLoggerLogic {
102
        private static final Pattern REMOTE_URL = Pattern.compile("\\b(https?://[^\\s)>]+)");
98
        private static final Pattern REMOTE_URL = Pattern.compile("\\b(https?://[^\\s)>]+)");
Lines 131-158 Link Here
131
        }
127
        }
132
    }
128
    }
133
129
134
    @ServiceProvider(service=HudsonLogger.class)
135
    public static final class PlainLogger implements HudsonLogger {
136
        public HudsonLogSession createSession(final HudsonJob job) {
137
            return new HudsonLogSession() {
138
                final PlainLoggerLogic logic = new PlainLoggerLogic(job, job.getName());
139
                public boolean handle(String line, OutputWriter stream) {
140
                    OutputListener link = logic.findHyperlink(line);
141
                    if (link != null) {
142
                        try {
143
                            stream.println(line, link);
144
                            return true;
145
                        } catch (IOException x) {
146
                            LOG.log(Level.INFO, null, x);
147
                        }
148
                    }
149
                    stream.println(line);
150
                    return true;
151
                }
152
            };
153
        }
154
    }
155
156
    private static class Hyperlink implements OutputListener {
130
    private static class Hyperlink implements OutputListener {
157
131
158
        private static final RequestProcessor RP = new RequestProcessor(Hyperlink.class);
132
        private static final RequestProcessor RP = new RequestProcessor(Hyperlink.class);
Lines 171-180 Link Here
171
            this.col = col;
145
            this.col = col;
172
        }
146
        }
173
147
148
        @Override
174
        public void outputLineAction(OutputEvent ev) {
149
        public void outputLineAction(OutputEvent ev) {
175
            acted(true);
150
            acted(true);
176
        }
151
        }
177
152
153
        @Override
178
        public void outputLineSelected(OutputEvent ev) {
154
        public void outputLineSelected(OutputEvent ev) {
179
            acted(false);
155
            acted(false);
180
        }
156
        }
Lines 182-187 Link Here
182
        @Messages({"# {0} - file path in workspace", "Hyperlinker.looking_for=Looking for {0}...", "# {0} - file path in workspace", "Hyperlinker.not_found=No file {0} found in remote workspace."})
158
        @Messages({"# {0} - file path in workspace", "Hyperlinker.looking_for=Looking for {0}...", "# {0} - file path in workspace", "Hyperlinker.not_found=No file {0} found in remote workspace."})
183
        private void acted(final boolean force) {
159
        private void acted(final boolean force) {
184
            RP.post(new Runnable() {
160
            RP.post(new Runnable() {
161
                @Override
185
                public void run() {
162
                public void run() {
186
                    FileObject f = null;
163
                    FileObject f = null;
187
                    Project p = ProjectHudsonProvider.getDefault().findAssociatedProject(ProjectHudsonProvider.Association.forJob(job));
164
                    Project p = ProjectHudsonProvider.getDefault().findAssociatedProject(ProjectHudsonProvider.Association.forJob(job));
Lines 207-230 Link Here
207
                        // XXX #159829: consider aligning local line number with remote line number somehow
184
                        // XXX #159829: consider aligning local line number with remote line number somehow
208
                    }
185
                    }
209
                    if (f == null) {
186
                    if (f == null) {
210
                        StatusDisplayer.getDefault().setStatusText(Hyperlinker_looking_for(path));
187
                        StatusDisplayer.getDefault().setStatusText(Bundle.Hyperlinker_looking_for(path));
211
                        f = job.getRemoteWorkspace().findResource(path);
188
                        f = job.getRemoteWorkspace().findResource(path);
212
                        LOG.log(Level.FINE, "Tried to find remote file at {0} using {1}", new Object[] {f, path});
189
                        LOG.log(Level.FINE, "Tried to find remote file at {0} using {1}", new Object[] {f, path});
213
                    }
190
                    }
214
                    if (f == null) {
191
                    if (f == null) {
215
                        if (force) {
192
                        if (force) {
216
                        StatusDisplayer.getDefault().setStatusText(Hyperlinker_not_found(path));
193
                        StatusDisplayer.getDefault().setStatusText(Bundle.Hyperlinker_not_found(path));
217
                            Toolkit.getDefaultToolkit().beep();
194
                            Toolkit.getDefaultToolkit().beep();
218
                        }
195
                        }
219
                        return;
196
                        return;
220
                    }
197
                    }
221
                    // XXX could be useful to select this file in the workspace node (see related #159838)
198
                    // XXX could be useful to select this file in the workspace node (see related #159838)
222
                    StatusDisplayer.getDefault().setStatusText(message);
199
                    StatusDisplayer.getDefault().setStatusText(message);
223
                    HudsonLogger.Helper.openAt(f, row, col, force);
200
                    HudsonLoggerHelper.openAt(f, row, col, force);
224
                }
201
                }
225
            });
202
            });
226
        }
203
        }
227
204
205
        @Override
228
        public void outputLineCleared(OutputEvent ev) {}
206
        public void outputLineCleared(OutputEvent ev) {}
229
207
230
        public @Override String toString() {
208
        public @Override String toString() {
Lines 241-252 Link Here
241
            this.u = u;
219
            this.u = u;
242
        }
220
        }
243
221
222
        @Override
244
        public void outputLineAction(OutputEvent ev) {
223
        public void outputLineAction(OutputEvent ev) {
245
            URLDisplayer.getDefault().showURL(u);
224
            URLDisplayer.getDefault().showURL(u);
246
        }
225
        }
247
226
227
        @Override
248
        public void outputLineSelected(OutputEvent ev) {}
228
        public void outputLineSelected(OutputEvent ev) {}
249
229
230
        @Override
250
        public void outputLineCleared(OutputEvent ev) {}
231
        public void outputLineCleared(OutputEvent ev) {}
251
232
252
        public @Override String toString() {
233
        public @Override String toString() {
(-)a/hudson/src/org/netbeans/modules/hudson/ui/SearchProviderImpl.java (-8 / +7 lines)
Lines 40-57 Link Here
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.ui;
43
package org.netbeans.modules.hudson.ui.impl;
44
44
45
import java.util.Locale;
45
import java.util.Locale;
46
import org.netbeans.modules.hudson.Installer;
47
import org.netbeans.modules.hudson.api.HudsonInstance;
46
import org.netbeans.modules.hudson.api.HudsonInstance;
48
import org.netbeans.modules.hudson.api.HudsonJob;
47
import org.netbeans.modules.hudson.api.HudsonJob;
49
import org.netbeans.modules.hudson.api.UI;
48
import org.netbeans.modules.hudson.api.HudsonManager;
50
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
49
import org.netbeans.modules.hudson.ui.api.UI;
50
import org.netbeans.modules.hudson.api.Utilities;
51
import org.netbeans.spi.quicksearch.SearchProvider;
51
import org.netbeans.spi.quicksearch.SearchProvider;
52
import org.netbeans.spi.quicksearch.SearchRequest;
52
import org.netbeans.spi.quicksearch.SearchRequest;
53
import org.netbeans.spi.quicksearch.SearchResponse;
53
import org.netbeans.spi.quicksearch.SearchResponse;
54
import static org.netbeans.modules.hudson.ui.Bundle.*;
55
import org.openide.util.NbBundle.Messages;
54
import org.openide.util.NbBundle.Messages;
56
55
57
@Messages("quicksearch=Hudson") // QuickSearch/Hudson#displayName
56
@Messages("quicksearch=Hudson") // QuickSearch/Hudson#displayName
Lines 62-68 Link Here
62
        if (text == null) {
61
        if (text == null) {
63
            return;
62
            return;
64
        }
63
        }
65
        if (!Installer.active()) {
64
        if (!Utilities.isHudsonSupportActive()) {
66
            return;
65
            return;
67
        }
66
        }
68
        work(text, response);
67
        work(text, response);
Lines 70-76 Link Here
70
69
71
    @Messages({"# {0} - server label", "# {1} - job name", "search_response=Hudson job {1} on {0}"})
70
    @Messages({"# {0} - server label", "# {1} - job name", "search_response=Hudson job {1} on {0}"})
72
    private void work(String text, SearchResponse response) {
71
    private void work(String text, SearchResponse response) {
73
        for (final HudsonInstance instance : HudsonManagerImpl.getDefault().getInstances()) {
72
        for (final HudsonInstance instance : HudsonManager.getAllInstances()) {
74
            for (HudsonJob job : instance.getJobs()) {
73
            for (HudsonJob job : instance.getJobs()) {
75
                final String name = job.getName();
74
                final String name = job.getName();
76
                // XXX could also search for text in instance name, and/or Maven modules
75
                // XXX could also search for text in instance name, and/or Maven modules
Lines 79-85 Link Here
79
                        @Override public void run() {
78
                        @Override public void run() {
80
                            UI.selectNode(instance.getUrl(), name);
79
                            UI.selectNode(instance.getUrl(), name);
81
                        }
80
                        }
82
                    }, search_response(instance.getName(), name))) {
81
                    }, Bundle.search_response(instance.getName(), name))) {
83
                        return;
82
                        return;
84
                    }
83
                    }
85
                }
84
                }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/nodes/HudsonFolderNode.java (-1 / +1 lines)
Lines 51-57 Link Here
51
import org.netbeans.modules.hudson.api.HudsonFolder;
51
import org.netbeans.modules.hudson.api.HudsonFolder;
52
import org.netbeans.modules.hudson.api.HudsonJob;
52
import org.netbeans.modules.hudson.api.HudsonJob;
53
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
53
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
54
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
54
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
55
import org.openide.filesystems.FileUtil;
55
import org.openide.filesystems.FileUtil;
56
import org.openide.loaders.DataFolder;
56
import org.openide.loaders.DataFolder;
57
import org.openide.nodes.AbstractNode;
57
import org.openide.nodes.AbstractNode;
(-)a/hudson/src/org/netbeans/modules/hudson/ui/nodes/HudsonInstanceNode.java (-8 / +84 lines)
Lines 45-50 Link Here
45
package org.netbeans.modules.hudson.ui.nodes;
45
package org.netbeans.modules.hudson.ui.nodes;
46
46
47
import java.io.IOException;
47
import java.io.IOException;
48
import java.lang.reflect.InvocationTargetException;
48
import java.util.ArrayList;
49
import java.util.ArrayList;
49
import java.util.Collections;
50
import java.util.Collections;
50
import java.util.LinkedList;
51
import java.util.LinkedList;
Lines 57-71 Link Here
57
import org.netbeans.modules.hudson.api.HudsonInstance;
58
import org.netbeans.modules.hudson.api.HudsonInstance;
58
import org.netbeans.modules.hudson.api.HudsonJob;
59
import org.netbeans.modules.hudson.api.HudsonJob;
59
import org.netbeans.modules.hudson.api.HudsonJob.Color;
60
import org.netbeans.modules.hudson.api.HudsonJob.Color;
61
import org.netbeans.modules.hudson.api.HudsonManager;
60
import org.netbeans.modules.hudson.api.HudsonVersion;
62
import org.netbeans.modules.hudson.api.HudsonVersion;
61
import org.netbeans.modules.hudson.api.HudsonView;
63
import org.netbeans.modules.hudson.api.HudsonView;
62
import org.netbeans.modules.hudson.api.Utilities;
64
import org.netbeans.modules.hudson.api.Utilities;
63
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
64
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
65
import static org.netbeans.modules.hudson.ui.nodes.Bundle.*;
65
import static org.netbeans.modules.hudson.ui.nodes.Bundle.*;
66
import org.openide.nodes.AbstractNode;
66
import org.openide.nodes.AbstractNode;
67
import org.openide.nodes.Children;
67
import org.openide.nodes.Children;
68
import org.openide.nodes.Node;
68
import org.openide.nodes.Node;
69
import org.openide.nodes.PropertySupport;
70
import org.openide.nodes.Sheet;
69
import org.openide.util.NbBundle.Messages;
71
import org.openide.util.NbBundle.Messages;
70
import org.openide.util.Union2;
72
import org.openide.util.Union2;
71
import org.openide.util.lookup.Lookups;
73
import org.openide.util.lookup.Lookups;
Lines 79-85 Link Here
79
    
81
    
80
    private static final String ICON_BASE = "org/netbeans/modules/hudson/ui/resources/instance.png"; // NOI18N
82
    private static final String ICON_BASE = "org/netbeans/modules/hudson/ui/resources/instance.png"; // NOI18N
81
    
83
    
82
    private HudsonInstanceImpl instance;
84
    private final HudsonInstance instance;
85
    private Sheet.Set set;
83
    
86
    
84
    private boolean warn = false;
87
    private boolean warn = false;
85
    private boolean run = false;
88
    private boolean run = false;
Lines 87-93 Link Here
87
    private boolean forbidden;
90
    private boolean forbidden;
88
    private boolean version = false;
91
    private boolean version = false;
89
    
92
    
90
    public HudsonInstanceNode(final HudsonInstanceImpl instance) {
93
    public HudsonInstanceNode(final HudsonInstance instance) {
91
        super(new InstanceNodeChildren(instance), Lookups.singleton(instance));
94
        super(new InstanceNodeChildren(instance), Lookups.singleton(instance));
92
        
95
        
93
        setName(instance.getUrl());
96
        setName(instance.getUrl());
Lines 156-168 Link Here
156
    }
159
    }
157
160
158
    public @Override void destroy() throws IOException {
161
    public @Override void destroy() throws IOException {
159
        HudsonManagerImpl.getDefault().removeInstance(instance);
162
        HudsonManager.removeInstance(instance);
160
    }
163
    }
161
164
162
    public @Override PropertySet[] getPropertySets() {
165
    public @Override PropertySet[] getPropertySets() {
163
        return new PropertySet[] {instance.getProperties().getSheetSet()};
166
        return new PropertySet[] {getSheetSet()};
164
    }
167
    }
165
    
168
    
169
    @Messages({
170
        "TXT_Instance_Prop_Name=Name",
171
        "DESC_Instance_Prop_Name=Hudson's instance name",
172
        "TXT_Instance_Prop_Url=URL",
173
        "DESC_Instance_Prop_Url=Hudson's instance URL",
174
        "TXT_Instance_Prop_Sync=Autosynchronization time",
175
        "DESC_Instance_Prop_Sync=Autosynchronization time in minutes (if it's 0 the autosynchronization is off)"
176
    })
177
    private Sheet.Set getSheetSet() {
178
        if (null == set) {
179
            set = Sheet.createPropertiesSet();
180
181
            // Set display name
182
            set.setDisplayName(instance.getName());
183
184
            // Put properties in
185
            set.put(new Node.Property<?>[]{
186
                new PropertySupport<String>("name", String.class, //NOI18N
187
                TXT_Instance_Prop_Name(),
188
                DESC_Instance_Prop_Name(),
189
                true, false) {
190
191
                    @Override
192
                    public String getValue() {
193
                        return instance.getName();
194
                    }
195
196
                    @Override
197
                    public void setValue(String val) {
198
                    }
199
                },
200
                new PropertySupport<String>("url", String.class, //NOI18N
201
                TXT_Instance_Prop_Url(),
202
                DESC_Instance_Prop_Url(),
203
                true, false) {
204
205
                    @Override
206
                    public String getValue() throws IllegalAccessException, InvocationTargetException {
207
                        return instance.getUrl();
208
                    }
209
210
                    @Override
211
                    public void setValue(String val) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
212
                    }
213
                },
214
                new PropertySupport<Integer>("sync", Integer.class, //NOI18N
215
                TXT_Instance_Prop_Sync(),
216
                DESC_Instance_Prop_Sync(),
217
                true, true) {
218
                    @Override
219
                    public Integer getValue() {
220
                        return instance.getSyncInterval();
221
                    }
222
223
                    @Override
224
                    public void setValue(Integer val) {
225
                        if (val == null || val < 0) {
226
                            throw new IllegalArgumentException();
227
                        }
228
                        instance.setSyncInterval(val);
229
                    }
230
231
                    public @Override
232
                    boolean canWrite() {
233
                        return instance.isPersisted();
234
                    }
235
                }
236
            });
237
        }
238
239
        return set;
240
    }
241
166
    private synchronized void refreshState() {
242
    private synchronized void refreshState() {
167
        alive = instance.isConnected();
243
        alive = instance.isConnected();
168
        forbidden = instance.isForbidden();
244
        forbidden = instance.isForbidden();
Lines 200-208 Link Here
200
    
276
    
201
    private static class InstanceNodeChildren extends Children.Keys<Union2<HudsonJob,HudsonFolder>> implements HudsonChangeListener {
277
    private static class InstanceNodeChildren extends Children.Keys<Union2<HudsonJob,HudsonFolder>> implements HudsonChangeListener {
202
        
278
        
203
        private final HudsonInstanceImpl instance;
279
        private final HudsonInstance instance;
204
        
280
        
205
        InstanceNodeChildren(HudsonInstanceImpl instance) {
281
        InstanceNodeChildren(HudsonInstance instance) {
206
            this.instance = instance;
282
            this.instance = instance;
207
            instance.addHudsonChangeListener(this);
283
            instance.addHudsonChangeListener(this);
208
            instance.prefs().addPreferenceChangeListener(new PreferenceChangeListener() {
284
            instance.prefs().addPreferenceChangeListener(new PreferenceChangeListener() {
(-)a/hudson/src/org/netbeans/modules/hudson/ui/nodes/HudsonJobBuildNode.java (-4 / +4 lines)
Lines 50-59 Link Here
50
import org.netbeans.modules.hudson.api.HudsonJob.Color;
50
import org.netbeans.modules.hudson.api.HudsonJob.Color;
51
import org.netbeans.modules.hudson.api.HudsonJobBuild;
51
import org.netbeans.modules.hudson.api.HudsonJobBuild;
52
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
52
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
53
import org.netbeans.modules.hudson.api.UI;
53
import org.netbeans.modules.hudson.api.Utilities;
54
import org.netbeans.modules.hudson.impl.HudsonJobBuildImpl;
54
import org.netbeans.modules.hudson.ui.api.UI;
55
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
55
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
56
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
56
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
57
import org.openide.nodes.AbstractNode;
57
import org.openide.nodes.AbstractNode;
58
import org.openide.nodes.ChildFactory;
58
import org.openide.nodes.ChildFactory;
59
import org.openide.nodes.Children;
59
import org.openide.nodes.Children;
Lines 75-81 Link Here
75
        if (build.isBuilding()) {
75
        if (build.isBuilding()) {
76
            effectiveColor = build.getJob().getColor();
76
            effectiveColor = build.getJob().getColor();
77
        } else {
77
        } else {
78
            effectiveColor = HudsonJobBuildImpl.getColorForBuild(build);
78
            effectiveColor = Utilities.getColorForBuild(build);
79
        }
79
        }
80
        try {
80
        try {
81
            htmlDisplayName = effectiveColor.colorizeDisplayName(XMLUtil.toElementContent(getDisplayName()));
81
            htmlDisplayName = effectiveColor.colorizeDisplayName(XMLUtil.toElementContent(getDisplayName()));
(-)a/hudson/src/org/netbeans/modules/hudson/ui/nodes/HudsonJobNode.java (-20 / +84 lines)
Lines 47-73 Link Here
47
import java.beans.PropertyChangeEvent;
47
import java.beans.PropertyChangeEvent;
48
import java.beans.PropertyChangeListener;
48
import java.beans.PropertyChangeListener;
49
import java.io.CharConversionException;
49
import java.io.CharConversionException;
50
import java.lang.reflect.InvocationTargetException;
50
import java.util.ArrayList;
51
import java.util.ArrayList;
51
import java.util.List;
52
import java.util.List;
52
import javax.swing.Action;
53
import javax.swing.Action;
53
import org.netbeans.modules.hudson.api.HudsonJob;
54
import org.netbeans.modules.hudson.api.HudsonJob;
54
import org.netbeans.modules.hudson.api.HudsonJob.Color;
55
import org.netbeans.modules.hudson.api.HudsonJob.Color;
55
import org.netbeans.modules.hudson.api.HudsonJobBuild;
56
import org.netbeans.modules.hudson.api.HudsonJobBuild;
56
import org.netbeans.modules.hudson.constants.HudsonInstanceConstants;
57
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
58
import org.netbeans.modules.hudson.impl.HudsonJobImpl;
59
import org.netbeans.modules.hudson.ui.actions.LogInAction;
57
import org.netbeans.modules.hudson.ui.actions.LogInAction;
60
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
58
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
61
import org.netbeans.modules.hudson.ui.actions.ProjectAssociationAction;
62
import org.netbeans.modules.hudson.ui.actions.StartJobAction;
59
import org.netbeans.modules.hudson.ui.actions.StartJobAction;
63
import org.netbeans.modules.hudson.ui.actions.ViewConfigAction;
60
import org.netbeans.modules.hudson.ui.actions.ViewConfigAction;
64
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
61
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
62
import org.netbeans.modules.hudson.constants.HudsonInstanceConstants;
63
import org.netbeans.modules.hudson.constants.HudsonJobConstants;
64
import org.netbeans.modules.hudson.ui.actions.ProjectAssociationAction;
65
import static org.netbeans.modules.hudson.ui.nodes.Bundle.*;
65
import static org.netbeans.modules.hudson.ui.nodes.Bundle.*;
66
import org.openide.actions.PropertiesAction;
66
import org.openide.actions.PropertiesAction;
67
import org.openide.nodes.AbstractNode;
67
import org.openide.nodes.AbstractNode;
68
import org.openide.nodes.ChildFactory;
68
import org.openide.nodes.ChildFactory;
69
import org.openide.nodes.Children;
69
import org.openide.nodes.Children;
70
import org.openide.nodes.Node;
70
import org.openide.nodes.Node;
71
import org.openide.nodes.PropertySupport;
71
import org.openide.nodes.Sheet;
72
import org.openide.nodes.Sheet;
72
import org.openide.util.NbBundle.Messages;
73
import org.openide.util.NbBundle.Messages;
73
import org.openide.util.WeakListeners;
74
import org.openide.util.WeakListeners;
Lines 85-90 Link Here
85
    private String htmlDisplayName;
86
    private String htmlDisplayName;
86
    private HudsonJob job;
87
    private HudsonJob job;
87
    private PropertyChangeListener watchedListener;
88
    private PropertyChangeListener watchedListener;
89
    private Sheet.Set set;
88
    
90
    
89
    public HudsonJobNode(HudsonJob job) {
91
    public HudsonJobNode(HudsonJob job) {
90
        super(makeChildren(job), Lookups.singleton(job));
92
        super(makeChildren(job), Lookups.singleton(job));
Lines 128-134 Link Here
128
    @Override
130
    @Override
129
    public Action[] getActions(boolean context) {
131
    public Action[] getActions(boolean context) {
130
        if (job.getColor() == Color.secured) {
132
        if (job.getColor() == Color.secured) {
131
            return new Action[] {new LogInAction((HudsonInstanceImpl) job.getInstance())};
133
            return new Action[] {new LogInAction(job.getInstance())};
132
        }
134
        }
133
        List<Action> actions = new ArrayList<Action>();
135
        List<Action> actions = new ArrayList<Action>();
134
        actions.add(SystemAction.get(StartJobAction.class));
136
        actions.add(SystemAction.get(StartJobAction.class));
Lines 148-174 Link Here
148
        Sheet s = super.createSheet();
150
        Sheet s = super.createSheet();
149
        
151
        
150
        // Put properties in
152
        // Put properties in
151
        s.put(((HudsonJobImpl) job).getSheetSet()); // XXX is cast necessary?
153
        s.put(getSheetSet()); // XXX is cast necessary?
152
        
154
        
153
        return s;
155
        return s;
154
    }
156
    }
155
    
157
    
156
    private void setWatchedListener() {
158
    @Messages({
157
        if (job instanceof HudsonJobImpl) {
159
        "TXT_Job_Prop_Name=Name",
158
            final HudsonJobImpl jobImpl = (HudsonJobImpl) job;
160
        "DESC_Job_Prop_Name=Hudson's job name",
159
            watchedListener = new PropertyChangeListener() {
161
        "TXT_Job_Prop_Url=URL",
160
                @Override
162
        "DESC_Job_Prop_Url=Hudson's job URL",
161
                public void propertyChange(PropertyChangeEvent evt) {
163
        "HudsonJobImpl.watched=Watched",
162
                    if (evt.getPropertyName().equals(
164
        "HudsonJobImpl.watched_desc=Whether you wish to be notified of failures in this job."
163
                            HudsonInstanceConstants.INSTANCE_SUPPRESSED_JOBS)) {
165
    })
164
                        setHudsonJob(HudsonJobNode.this.job);
166
    private Sheet.Set getSheetSet() {
167
        if (null == set) {
168
            set = Sheet.createPropertiesSet();
169
170
            // Set display name
171
            set.setDisplayName(getDisplayName());
172
173
            // Put properties in
174
            set.put(new Node.Property<?>[]{
175
                new PropertySupport<String>(HudsonJobConstants.JOB_NAME, String.class,
176
                TXT_Job_Prop_Name(),
177
                DESC_Job_Prop_Name(), true, false) {
178
179
                    @Override
180
                    public String getValue() {
181
                        return job.getName();
182
                    }
183
184
                    @Override
185
                    public void setValue(String val) {
186
                    }
187
                },
188
                new PropertySupport<String>(HudsonJobConstants.JOB_URL, String.class,
189
                TXT_Job_Prop_Url(),
190
                DESC_Job_Prop_Url(), true, false) {
191
192
                    @Override
193
                    public String getValue() throws IllegalAccessException, InvocationTargetException {
194
                        return job.getUrl();
195
                    }
196
197
                    @Override
198
                    public void setValue(String val) {
199
                    }
200
201
                },
202
                new PropertySupport.ReadWrite<Boolean>("salient", Boolean.TYPE, // NOI18N
203
                HudsonJobImpl_watched(),
204
                HudsonJobImpl_watched_desc()) {
205
                    @Override
206
                    public Boolean getValue() {
207
                        return job.isSalient();
208
                    }
209
210
                    @Override
211
                    public void setValue(Boolean val) {
212
                        if (!getValue().equals(val)) {
213
                            job.setSalient(val);
214
                        }
165
                    }
215
                    }
166
                }
216
                }
167
            };
217
            });
168
            jobImpl.getInstance().getProperties().addPropertyChangeListener(
169
                    WeakListeners.propertyChange(watchedListener,
170
                    jobImpl.getInstance().getProperties()));
171
        }
218
        }
219
        return set;
220
    }
221
222
    private void setWatchedListener() {
223
224
        watchedListener = new PropertyChangeListener() {
225
            @Override
226
            public void propertyChange(PropertyChangeEvent evt) {
227
                if (evt.getPropertyName().equals(
228
                        HudsonInstanceConstants.INSTANCE_SUPPRESSED_JOBS)) {
229
                    setHudsonJob(HudsonJobNode.this.job);
230
                }
231
            }
232
        };
233
        job.getInstance().addPropertyChangeListener(
234
                WeakListeners.propertyChange(watchedListener,
235
                job.getInstance()));
172
    }
236
    }
173
237
174
    @Messages({
238
    @Messages({
(-)a/hudson/src/org/netbeans/modules/hudson/ui/nodes/HudsonMavenModuleBuildNode.java (-2 / +2 lines)
Lines 47-55 Link Here
47
import java.util.List;
47
import java.util.List;
48
import javax.swing.Action;
48
import javax.swing.Action;
49
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
49
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
50
import org.netbeans.modules.hudson.api.UI;
50
import org.netbeans.modules.hudson.ui.api.UI;
51
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
51
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
52
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
52
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
53
import org.openide.nodes.AbstractNode;
53
import org.openide.nodes.AbstractNode;
54
import org.openide.nodes.ChildFactory;
54
import org.openide.nodes.ChildFactory;
55
import org.openide.nodes.Children;
55
import org.openide.nodes.Children;
(-)a/hudson/src/org/netbeans/modules/hudson/ui/nodes/HudsonRootNode.java (-7 / +10 lines)
Lines 50-57 Link Here
50
import javax.swing.Action;
50
import javax.swing.Action;
51
import org.netbeans.api.core.ide.ServicesTabNodeRegistration;
51
import org.netbeans.api.core.ide.ServicesTabNodeRegistration;
52
import org.netbeans.modules.hudson.api.HudsonChangeListener;
52
import org.netbeans.modules.hudson.api.HudsonChangeListener;
53
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
53
import org.netbeans.modules.hudson.api.HudsonInstance;
54
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
54
import org.netbeans.modules.hudson.api.HudsonManager;
55
import org.netbeans.modules.hudson.ui.actions.AddInstanceAction;
55
import org.netbeans.modules.hudson.ui.actions.AddInstanceAction;
56
import static org.netbeans.modules.hudson.ui.nodes.Bundle.*;
56
import static org.netbeans.modules.hudson.ui.nodes.Bundle.*;
57
import org.openide.nodes.AbstractNode;
57
import org.openide.nodes.AbstractNode;
Lines 90-113 Link Here
90
        return actions.toArray(new Action[actions.size()]);
90
        return actions.toArray(new Action[actions.size()]);
91
    }
91
    }
92
    
92
    
93
    private static class RootNodeChildren extends ChildFactory<HudsonInstanceImpl> implements HudsonChangeListener {
93
    private static class RootNodeChildren extends ChildFactory<HudsonInstance> implements HudsonChangeListener {
94
        
94
        
95
        public RootNodeChildren() {
95
        public RootNodeChildren() {
96
            HudsonManagerImpl.getDefault().addHudsonChangeListener(this);
96
            HudsonManager.addHudsonChangeListener(this);
97
        }
97
        }
98
98
99
        protected @Override Node createNodeForKey(HudsonInstanceImpl key) {
99
        protected @Override Node createNodeForKey(HudsonInstance key) {
100
            return new HudsonInstanceNode(key);
100
            return new HudsonInstanceNode(key);
101
        }
101
        }
102
        
102
        
103
        protected boolean createKeys(List<HudsonInstanceImpl> toPopulate) {
103
        @Override
104
            toPopulate.addAll(HudsonManagerImpl.getDefault().getInstances());
104
        protected boolean createKeys(List<HudsonInstance> toPopulate) {
105
            toPopulate.addAll(HudsonManager.getAllInstances());
105
            Collections.sort(toPopulate);
106
            Collections.sort(toPopulate);
106
            return true;
107
            return true;
107
        }
108
        }
108
109
110
        @Override
109
        public void stateChanged() {}
111
        public void stateChanged() {}
110
        
112
        
113
        @Override
111
        public void contentChanged() {
114
        public void contentChanged() {
112
            refresh(false);
115
            refresh(false);
113
        }
116
        }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/notification/ProblemNotification.java (-6 / +6 lines)
Lines 49-55 Link Here
49
import org.netbeans.modules.hudson.api.HudsonJob;
49
import org.netbeans.modules.hudson.api.HudsonJob;
50
import org.netbeans.modules.hudson.api.HudsonJobBuild;
50
import org.netbeans.modules.hudson.api.HudsonJobBuild;
51
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
51
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
52
import org.netbeans.modules.hudson.api.UI;
52
import org.netbeans.modules.hudson.ui.api.UI;
53
import org.openide.DialogDisplayer;
53
import org.openide.DialogDisplayer;
54
import org.openide.NotifyDescriptor;
54
import org.openide.NotifyDescriptor;
55
import org.openide.awt.Notification;
55
import org.openide.awt.Notification;
Lines 58-64 Link Here
58
import org.openide.util.ImageUtilities;
58
import org.openide.util.ImageUtilities;
59
import org.openide.util.NbBundle.Messages;
59
import org.openide.util.NbBundle.Messages;
60
import org.openide.util.RequestProcessor;
60
import org.openide.util.RequestProcessor;
61
import static org.netbeans.modules.hudson.ui.notification.Bundle.*;
62
import org.openide.awt.NotificationDisplayer.Category;
61
import org.openide.awt.NotificationDisplayer.Category;
63
import org.openide.util.lookup.Lookups;
62
import org.openide.util.lookup.Lookups;
64
63
Lines 90-96 Link Here
90
    })
89
    })
91
    private String getTitle() {
90
    private String getTitle() {
92
        // XXX use HudsonJobBuild.getDisplayName
91
        // XXX use HudsonJobBuild.getDisplayName
93
        return failed ? ProblemNotification_title_failed(job.getDisplayName(), build) : ProblemNotification_title_unstable(job.getDisplayName(), build);
92
        return failed ? Bundle.ProblemNotification_title_failed(job.getDisplayName(), build) : Bundle.ProblemNotification_title_unstable(job.getDisplayName(), build);
94
    }
93
    }
95
94
96
    @Messages({
95
    @Messages({
Lines 98-110 Link Here
98
        "ProblemNotification.description.unstable=Some tests failed."
97
        "ProblemNotification.description.unstable=Some tests failed."
99
    })
98
    })
100
    String showFailureText() {
99
    String showFailureText() {
101
        return failed ? ProblemNotification_description_failed() : ProblemNotification_description_unstable();
100
        return failed ? Bundle.ProblemNotification_description_failed() : Bundle.ProblemNotification_description_unstable();
102
    }
101
    }
103
102
104
    void showFailure() {
103
    void showFailure() {
105
        // BuildHandleImpl.getDefaultAction similar but not identical.
104
        // BuildHandleImpl.getDefaultAction similar but not identical.
106
        UI.selectNode(job.getInstance().getUrl(), job.getName(), Integer.toString(build));
105
        UI.selectNode(job.getInstance().getUrl(), job.getName(), Integer.toString(build));
107
        RequestProcessor.getDefault().post(new Runnable() {
106
        RequestProcessor.getDefault().post(new Runnable() {
107
            @Override
108
            public void run() {
108
            public void run() {
109
                for (HudsonJobBuild b : job.getBuilds()) {
109
                for (HudsonJobBuild b : job.getBuilds()) {
110
                    if (b.getNumber() == build) {
110
                    if (b.getNumber() == build) {
Lines 140-147 Link Here
140
    })
140
    })
141
    void ignore() { // #161601
141
    void ignore() { // #161601
142
        if (DialogDisplayer.getDefault().notify(new NotifyDescriptor.Confirmation(
142
        if (DialogDisplayer.getDefault().notify(new NotifyDescriptor.Confirmation(
143
                ProblemNotification_ignore_question(job.getDisplayName(), job.getInstance().getName()),
143
                Bundle.ProblemNotification_ignore_question(job.getDisplayName(), job.getInstance().getName()),
144
                ProblemNotification_ignore_title(job.getDisplayName()),
144
                Bundle.ProblemNotification_ignore_title(job.getDisplayName()),
145
                NotifyDescriptor.OK_CANCEL_OPTION)) == NotifyDescriptor.OK_OPTION) {
145
                NotifyDescriptor.OK_CANCEL_OPTION)) == NotifyDescriptor.OK_OPTION) {
146
            job.setSalient(false);
146
            job.setSalient(false);
147
        }
147
        }
(-)a/hudson/src/org/netbeans/modules/hudson/ui/notification/ProblemNotificationController.java (-3 / +3 lines)
Lines 48-65 Link Here
48
import java.util.logging.Level;
48
import java.util.logging.Level;
49
import java.util.logging.Logger;
49
import java.util.logging.Logger;
50
import java.util.prefs.Preferences;
50
import java.util.prefs.Preferences;
51
import org.netbeans.modules.hudson.api.HudsonInstance;
51
import org.netbeans.modules.hudson.api.HudsonJob;
52
import org.netbeans.modules.hudson.api.HudsonJob;
52
import org.netbeans.modules.hudson.api.HudsonJob.Color;
53
import org.netbeans.modules.hudson.api.HudsonJob.Color;
53
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
54
54
55
public class ProblemNotificationController {
55
public class ProblemNotificationController {
56
56
57
    private static final Logger LOG = Logger.getLogger(ProblemNotificationController.class.getName());
57
    private static final Logger LOG = Logger.getLogger(ProblemNotificationController.class.getName());
58
58
59
    private final HudsonInstanceImpl instance;
59
    private final HudsonInstance instance;
60
    private final Set<ProblemNotification> notifications = new HashSet<ProblemNotification>();
60
    private final Set<ProblemNotification> notifications = new HashSet<ProblemNotification>();
61
61
62
    public ProblemNotificationController(HudsonInstanceImpl instance) {
62
    public ProblemNotificationController(HudsonInstance instance) {
63
        this.instance = instance;
63
        this.instance = instance;
64
    }
64
    }
65
65
(-)a/hudson/src/org/netbeans/modules/hudson/spi/ProjectHudsonJobCreatorFactory.java (-68 / +5 lines)
Lines 40-58 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.spi;
43
package org.netbeans.modules.hudson.ui.spi;
44
44
45
import java.io.File;
45
import java.io.File;
46
import java.io.IOException;
46
import java.io.IOException;
47
import javax.swing.JButton;
48
import javax.swing.JComponent;
47
import javax.swing.JComponent;
49
import javax.swing.event.ChangeListener;
48
import javax.swing.event.ChangeListener;
50
import org.netbeans.api.project.Project;
49
import org.netbeans.api.project.Project;
51
import org.netbeans.api.project.ProjectInformation;
50
import org.netbeans.api.project.ProjectInformation;
52
import org.openide.NotifyDescriptor;
51
import org.netbeans.modules.hudson.spi.HudsonSCM;
52
import org.netbeans.modules.hudson.spi.HudsonSCM.ConfigurationStatus;
53
import org.openide.util.Lookup;
53
import org.openide.util.Lookup;
54
import org.openide.util.NbBundle.Messages;
54
import org.openide.util.NbBundle.Messages;
55
import static org.netbeans.modules.hudson.spi.Bundle.*;
56
import org.w3c.dom.Document;
55
import org.w3c.dom.Document;
57
import org.w3c.dom.Element;
56
import org.w3c.dom.Element;
58
57
Lines 146-216 Link Here
146
    }
145
    }
147
146
148
    /**
147
    /**
149
     * Return value of {@link ProjectHudsonJobCreator#error}.
150
     */
151
    final class ConfigurationStatus {
152
153
        private String errorMessage;
154
        private String warningMessage;
155
        private JButton extraButton;
156
157
        private ConfigurationStatus() {}
158
159
        /** Creates a valid configuration. */
160
        public static ConfigurationStatus valid() {
161
            return new ConfigurationStatus();
162
        }
163
164
        /** Creates a configuration with a fatal error. */
165
        public static ConfigurationStatus withError(String error) {
166
            ConfigurationStatus s = new ConfigurationStatus();
167
            s.errorMessage = error;
168
            return s;
169
        }
170
171
        /** Creates a configuration with a nonfatal warning. */
172
        public static ConfigurationStatus withWarning(String warning) {
173
            ConfigurationStatus s = new ConfigurationStatus();
174
            s.warningMessage = warning;
175
            return s;
176
        }
177
178
        /**
179
         * Creates a similar configuration but with an extra button added to the dialog.
180
         * @see NotifyDescriptor#setAdditionalOptions
181
         */
182
        public ConfigurationStatus withExtraButton(JButton extraButton) {
183
            if (this.extraButton != null) {
184
                throw new IllegalArgumentException();
185
            }
186
            ConfigurationStatus s = new ConfigurationStatus();
187
            s.errorMessage = errorMessage;
188
            s.warningMessage = warningMessage;
189
            s.extraButton = extraButton;
190
            return s;
191
        }
192
193
        /** for internal use only */
194
        public String getErrorMessage() {
195
            return errorMessage;
196
        }
197
198
        /** for internal use only */
199
        public String getWarningMessage() {
200
            return warningMessage;
201
        }
202
203
        /** for internal use only */
204
        public JButton getExtraButton() {
205
            return extraButton;
206
        }
207
208
    }
209
210
    /**
211
     * Utilities which can be used by {@link ProjectHudsonJobCreator#configure}.
148
     * Utilities which can be used by {@link ProjectHudsonJobCreator#configure}.
212
     */
149
     */
213
    class Helper {
150
    public final class Helper {
214
151
215
        private Helper() {}
152
        private Helper() {}
216
153
Lines 234-240 Link Here
234
         */
171
         */
235
        @Messages("ProjectHudsonJobCreatorFactory.no_vcs=The project does not use any supported version control system.")
172
        @Messages("ProjectHudsonJobCreatorFactory.no_vcs=The project does not use any supported version control system.")
236
        public static ConfigurationStatus noSCMError() {
173
        public static ConfigurationStatus noSCMError() {
237
            return ConfigurationStatus.withError(ProjectHudsonJobCreatorFactory_no_vcs());
174
            return ConfigurationStatus.withError(Bundle.ProjectHudsonJobCreatorFactory_no_vcs());
238
        }
175
        }
239
176
240
        /**
177
        /**
(-)a/hudson/src/org/netbeans/modules/hudson/spi/ProjectHudsonProvider.java (-3 / +3 lines)
Lines 42-48 Link Here
42
 * made subject to such option by the copyright holder.
42
 * made subject to such option by the copyright holder.
43
 */
43
 */
44
44
45
package org.netbeans.modules.hudson.spi;
45
package org.netbeans.modules.hudson.ui.spi;
46
46
47
import java.net.URI;
47
import java.net.URI;
48
import java.util.Arrays;
48
import java.util.Arrays;
Lines 59-65 Link Here
59
import org.netbeans.modules.hudson.api.HudsonFolder;
59
import org.netbeans.modules.hudson.api.HudsonFolder;
60
import org.netbeans.modules.hudson.api.HudsonInstance;
60
import org.netbeans.modules.hudson.api.HudsonInstance;
61
import org.netbeans.modules.hudson.api.HudsonJob;
61
import org.netbeans.modules.hudson.api.HudsonJob;
62
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
62
import org.netbeans.modules.hudson.api.HudsonManager;
63
import org.netbeans.modules.hudson.api.Utilities;
63
import org.netbeans.modules.hudson.api.Utilities;
64
import org.openide.util.Lookup;
64
import org.openide.util.Lookup;
65
65
Lines 275-281 Link Here
275
            if (jobPath == null || jobPath.length < 2) { // no job name
275
            if (jobPath == null || jobPath.length < 2) { // no job name
276
                return null;
276
                return null;
277
            }
277
            }
278
            HudsonInstance instance = HudsonManagerImpl.getDefault().getInstance(jobPath[0]);
278
            HudsonInstance instance = HudsonManager.getInstance(jobPath[0]);
279
            if (instance == null) {
279
            if (instance == null) {
280
                return null;
280
                return null;
281
            }
281
            }
(-)a/hudson/src/org/netbeans/modules/hudson/util/UsageLogging.java (-1 / +1 lines)
Lines 39-45 Link Here
39
 *
39
 *
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2011 Sun Microsystems, Inc.
41
 */
41
 */
42
package org.netbeans.modules.hudson.util;
42
package org.netbeans.modules.hudson.ui.util;
43
43
44
import java.util.ResourceBundle;
44
import java.util.ResourceBundle;
45
import java.util.logging.Level;
45
import java.util.logging.Level;
(-)a/hudson/src/org/netbeans/modules/hudson/ui/wizard/InstanceDialog.java (-4 / +4 lines)
Lines 56-66 Link Here
56
import javax.swing.JButton;
56
import javax.swing.JButton;
57
import org.netbeans.modules.hudson.api.ConnectionBuilder;
57
import org.netbeans.modules.hudson.api.ConnectionBuilder;
58
import org.netbeans.modules.hudson.api.HudsonInstance;
58
import org.netbeans.modules.hudson.api.HudsonInstance;
59
import org.netbeans.modules.hudson.api.HudsonManager;
59
import org.netbeans.modules.hudson.api.HudsonVersion;
60
import org.netbeans.modules.hudson.api.HudsonVersion;
60
import org.netbeans.modules.hudson.api.UI;
61
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
62
import org.netbeans.modules.hudson.api.Utilities;
61
import org.netbeans.modules.hudson.api.Utilities;
63
import org.netbeans.modules.hudson.util.UsageLogging;
62
import org.netbeans.modules.hudson.ui.api.UI;
63
import org.netbeans.modules.hudson.ui.util.UsageLogging;
64
import org.openide.DialogDescriptor;
64
import org.openide.DialogDescriptor;
65
import org.openide.DialogDisplayer;
65
import org.openide.DialogDisplayer;
66
import org.openide.NotifyDescriptor;
66
import org.openide.NotifyDescriptor;
Lines 138-144 Link Here
138
                    problem(NbBundle.getMessage(InstanceDialog.class, "MSG_FailedToConnect"));
138
                    problem(NbBundle.getMessage(InstanceDialog.class, "MSG_FailedToConnect"));
139
                    return;
139
                    return;
140
                }
140
                }
141
                created = HudsonInstanceImpl.createHudsonInstance(panel.getDisplayName(), panel.getUrl(), String.valueOf(panel.getSyncTime()));
141
                created = HudsonManager.addInstance(panel.getDisplayName(), panel.getUrl(), panel.getSyncTime(), true);
142
                EventQueue.invokeLater(new Runnable() {
142
                EventQueue.invokeLater(new Runnable() {
143
                    public void run() {
143
                    public void run() {
144
                        dialog.dispose();
144
                        dialog.dispose();
(-)a/hudson/src/org/netbeans/modules/hudson/ui/wizard/InstancePropertiesVisual.java (-3 / +3 lines)
Lines 51-57 Link Here
51
import javax.swing.event.DocumentEvent;
51
import javax.swing.event.DocumentEvent;
52
import javax.swing.event.DocumentListener;
52
import javax.swing.event.DocumentListener;
53
import org.netbeans.api.options.OptionsDisplayer;
53
import org.netbeans.api.options.OptionsDisplayer;
54
import org.netbeans.modules.hudson.impl.HudsonManagerImpl;
54
import org.netbeans.modules.hudson.api.HudsonManager;
55
import org.openide.NotificationLineSupport;
55
import org.openide.NotificationLineSupport;
56
import org.openide.util.NbBundle;
56
import org.openide.util.NbBundle;
57
57
Lines 257-263 Link Here
257
            msgs.setInformationMessage(NbBundle.getMessage(InstanceDialog.class, "MSG_EmptyName"));
257
            msgs.setInformationMessage(NbBundle.getMessage(InstanceDialog.class, "MSG_EmptyName"));
258
            return;
258
            return;
259
        }
259
        }
260
        if (HudsonManagerImpl.getDefault().getInstanceByName(name) != null) {
260
        if (HudsonManager.getInstanceByName(name) != null) {
261
            msgs.setErrorMessage(NbBundle.getMessage(InstanceDialog.class, "MSG_ExistName"));
261
            msgs.setErrorMessage(NbBundle.getMessage(InstanceDialog.class, "MSG_ExistName"));
262
            return;
262
            return;
263
        }
263
        }
Lines 279-285 Link Here
279
            msgs.setErrorMessage(x.getLocalizedMessage());
279
            msgs.setErrorMessage(x.getLocalizedMessage());
280
            return;
280
            return;
281
        }
281
        }
282
        if (HudsonManagerImpl.getDefault().getInstance(url) != null) {
282
        if (HudsonManager.getInstance(url) != null) {
283
            msgs.setErrorMessage(NbBundle.getMessage(InstanceDialog.class, "MSG_ExistUrl"));
283
            msgs.setErrorMessage(NbBundle.getMessage(InstanceDialog.class, "MSG_ExistUrl"));
284
            return;
284
            return;
285
        }
285
        }
(-)a/hudson/test/unit/src/org/netbeans/modules/hudson/ui/actions/HyperlinkerTest.java (-4 / +4 lines)
Lines 40-53 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.ui.actions;
43
package org.netbeans.modules.hudson.ui.impl;
44
44
45
import org.netbeans.junit.NbTestCase;
45
import org.netbeans.junit.NbTestCase;
46
import org.netbeans.modules.hudson.ui.actions.Hyperlinker.PlainLoggerLogic;
46
import org.netbeans.modules.hudson.ui.impl.PlainLogger.PlainLoggerLogic;
47
47
48
public class HyperlinkerTest extends NbTestCase {
48
public class PlainLoggerTest extends NbTestCase {
49
49
50
    public HyperlinkerTest(String n) {
50
    public PlainLoggerTest(String n) {
51
        super(n);
51
        super(n);
52
    }
52
    }
53
53
(-)a/hudson/test/unit/src/org/netbeans/modules/hudson/spi/ProjectHudsonProviderTest.java (-2 / +2 lines)
Lines 40-49 Link Here
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
40
 * Portions Copyrighted 2009 Sun Microsystems, Inc.
41
 */
41
 */
42
42
43
package org.netbeans.modules.hudson.spi;
43
package org.netbeans.modules.hudson.ui.spi;
44
44
45
import org.netbeans.junit.NbTestCase;
45
import org.netbeans.junit.NbTestCase;
46
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider.Association;
46
import org.netbeans.modules.hudson.ui.spi.ProjectHudsonProvider.Association;
47
47
48
public class ProjectHudsonProviderTest extends NbTestCase {
48
public class ProjectHudsonProviderTest extends NbTestCase {
49
49
(-)a/hudson/manifest.mf (-1 / +1 lines)
Lines 2-6 Link Here
2
OpenIDE-Module: org.netbeans.modules.hudson
2
OpenIDE-Module: org.netbeans.modules.hudson
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/hudson/Bundle.properties
3
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/hudson/Bundle.properties
4
OpenIDE-Module-Layer: org/netbeans/modules/hudson/layer.xml
4
OpenIDE-Module-Layer: org/netbeans/modules/hudson/layer.xml
5
OpenIDE-Module-Specification-Version: 1.34
5
OpenIDE-Module-Specification-Version: 2.0
6
6
(-)a/hudson/nbproject/project.xml (-78 / +3 lines)
Lines 33-47 Link Here
33
                    </run-dependency>
33
                    </run-dependency>
34
                </dependency>
34
                </dependency>
35
                <dependency>
35
                <dependency>
36
                    <code-name-base>org.netbeans.core.ide</code-name-base>
37
                    <build-prerequisite/>
38
                    <compile-dependency/>
39
                    <run-dependency>
40
                        <release-version>1</release-version>
41
                        <specification-version>1.15</specification-version>
42
                    </run-dependency>
43
                </dependency>
44
                <dependency>
45
                    <code-name-base>org.netbeans.libs.commons_net</code-name-base>
36
                    <code-name-base>org.netbeans.libs.commons_net</code-name-base>
46
                    <build-prerequisite/>
37
                    <build-prerequisite/>
47
                    <compile-dependency/>
38
                    <compile-dependency/>
Lines 51-74 Link Here
51
                    </run-dependency>
42
                    </run-dependency>
52
                </dependency>
43
                </dependency>
53
                <dependency>
44
                <dependency>
54
                    <code-name-base>org.netbeans.modules.diff</code-name-base>
55
                    <build-prerequisite/>
56
                    <compile-dependency/>
57
                    <run-dependency>
58
                        <release-version>1</release-version>
59
                        <specification-version>1.21</specification-version>
60
                    </run-dependency>
61
                </dependency>
62
                <dependency>
63
                    <code-name-base>org.netbeans.modules.gsf.testrunner</code-name-base>
64
                    <build-prerequisite/>
65
                    <compile-dependency/>
66
                    <run-dependency>
67
                        <release-version>1</release-version>
68
                        <specification-version>1.26</specification-version>
69
                    </run-dependency>
70
                </dependency>
71
                <dependency>
72
                    <code-name-base>org.netbeans.modules.keyring</code-name-base>
45
                    <code-name-base>org.netbeans.modules.keyring</code-name-base>
73
                    <build-prerequisite/>
46
                    <build-prerequisite/>
74
                    <compile-dependency/>
47
                    <compile-dependency/>
Lines 77-117 Link Here
77
                    </run-dependency>
50
                    </run-dependency>
78
                </dependency>
51
                </dependency>
79
                <dependency>
52
                <dependency>
80
                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
81
                    <build-prerequisite/>
82
                    <compile-dependency/>
83
                    <run-dependency>
84
                        <release-version>1</release-version>
85
                        <specification-version>1.5</specification-version>
86
                    </run-dependency>
87
                </dependency>
88
                <dependency>
89
                    <code-name-base>org.netbeans.modules.projectapi</code-name-base>
90
                    <build-prerequisite/>
91
                    <compile-dependency/>
92
                    <run-dependency>
93
                        <release-version>1</release-version>
94
                        <specification-version>1.16</specification-version>
95
                    </run-dependency>
96
                </dependency>
97
                <dependency>
98
                    <code-name-base>org.netbeans.modules.projectuiapi</code-name-base>
99
                    <build-prerequisite/>
100
                    <compile-dependency/>
101
                    <run-dependency>
102
                        <release-version>1</release-version>
103
                        <specification-version>1.23.0.6</specification-version>
104
                    </run-dependency>
105
                </dependency>
106
                <dependency>
107
                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
108
                    <build-prerequisite/>
109
                    <compile-dependency/>
110
                    <run-dependency>
111
                        <specification-version>1.13</specification-version>
112
                    </run-dependency>
113
                </dependency>
114
                <dependency>
115
                    <code-name-base>org.openide.actions</code-name-base>
53
                    <code-name-base>org.openide.actions</code-name-base>
116
                    <build-prerequisite/>
54
                    <build-prerequisite/>
117
                    <compile-dependency/>
55
                    <compile-dependency/>
Lines 136-149 Link Here
136
                    </run-dependency>
74
                    </run-dependency>
137
                </dependency>
75
                </dependency>
138
                <dependency>
76
                <dependency>
139
                    <code-name-base>org.openide.explorer</code-name-base>
140
                    <build-prerequisite/>
141
                    <compile-dependency/>
142
                    <run-dependency>
143
                        <specification-version>6.18</specification-version>
144
                    </run-dependency>
145
                </dependency>
146
                <dependency>
147
                    <code-name-base>org.openide.filesystems</code-name-base>
77
                    <code-name-base>org.openide.filesystems</code-name-base>
148
                    <build-prerequisite/>
78
                    <build-prerequisite/>
149
                    <compile-dependency/>
79
                    <compile-dependency/>
Lines 176-189 Link Here
176
                    </run-dependency>
106
                    </run-dependency>
177
                </dependency>
107
                </dependency>
178
                <dependency>
108
                <dependency>
179
                    <code-name-base>org.openide.nodes</code-name-base>
180
                    <build-prerequisite/>
181
                    <compile-dependency/>
182
                    <run-dependency>
183
                        <specification-version>7.27</specification-version>
184
                    </run-dependency>
185
                </dependency>
186
                <dependency>
187
                    <code-name-base>org.openide.text</code-name-base>
109
                    <code-name-base>org.openide.text</code-name-base>
188
                    <build-prerequisite/>
110
                    <build-prerequisite/>
189
                    <compile-dependency/>
111
                    <compile-dependency/>
Lines 239-246 Link Here
239
                <friend>org.netbeans.modules.hudson.php</friend>
161
                <friend>org.netbeans.modules.hudson.php</friend>
240
                <friend>org.netbeans.modules.hudson.subversion</friend>
162
                <friend>org.netbeans.modules.hudson.subversion</friend>
241
                <friend>org.netbeans.modules.hudson.tasklist</friend>
163
                <friend>org.netbeans.modules.hudson.tasklist</friend>
164
                <friend>org.netbeans.modules.hudson.ui</friend>
242
                <friend>org.netbeans.modules.odcs.hudson</friend>
165
                <friend>org.netbeans.modules.odcs.hudson</friend>
243
                <package>org.netbeans.modules.hudson.api</package>
166
                <package>org.netbeans.modules.hudson.api</package>
167
                <package>org.netbeans.modules.hudson.api.ui</package>
168
                <package>org.netbeans.modules.hudson.constants</package>
244
                <package>org.netbeans.modules.hudson.spi</package>
169
                <package>org.netbeans.modules.hudson.spi</package>
245
            </friend-packages>
170
            </friend-packages>
246
        </data>
171
        </data>
(-)a/hudson/src/org/netbeans/modules/hudson/api/HudsonInstance.java (+60 lines)
Lines 44-52 Link Here
44
44
45
package org.netbeans.modules.hudson.api;
45
package org.netbeans.modules.hudson.api;
46
46
47
import java.beans.PropertyChangeListener;
47
import java.util.Collection;
48
import java.util.Collection;
49
import java.util.List;
48
import java.util.prefs.Preferences;
50
import java.util.prefs.Preferences;
49
import javax.swing.Action;
51
import javax.swing.Action;
52
import org.netbeans.api.annotations.common.CheckForNull;
53
import org.netbeans.api.annotations.common.NullAllowed;
50
import org.openide.awt.ActionReference;
54
import org.openide.awt.ActionReference;
51
55
52
/**
56
/**
Lines 138-143 Link Here
138
    Preferences prefs();
142
    Preferences prefs();
139
143
140
    /**
144
    /**
145
     * Get list of preferred jobs.
146
     *
147
     * @return List of preferred jobs (can be empty), or null if no preferred
148
     * jobs have been set (i.e. all jobs are preferred).
149
     */
150
    @CheckForNull List<String> getPreferredJobs();
151
152
    /**
153
     * Set list of preferred jobs. Null can be passed, see
154
     * {@link #getPreferredJobs()}.
155
     *
156
     * Use with caution. Safer way to work with preferred jobs is using
157
     * {@link HudsonJob#setSalient(boolean)}.
158
     *
159
     * @param preferredJobs List of names of preferred jobs, can be null (i.e.
160
     * all jobs are preferred), or empty list (no job is preferred).
161
     */
162
    void setPreferredJobs(@NullAllowed List<String> preferredJobs);
163
164
    /**
165
     * Initiate synchronization: fetching refreshed job data from the server.
166
     * Will run asynchronously.
167
     *
168
     * @param login To prompt for login if the anonymous user cannot even see
169
     * the job list; set to true for explicit user gesture, false otherwise.
170
     */
171
    void synchronize(boolean login);
172
173
    /**
174
     * @return True if connection to the server if forbidden.
175
     */
176
    boolean isForbidden();
177
178
    /**
179
     * @return Info about persistence, and persistence-related features of the
180
     * instance.
181
     */
182
    public Persistence getPersistence();
183
184
    /**
185
     * @return Synchronization interval in minutes.
186
     */
187
    public int getSyncInterval();
188
189
    /**
190
     * Set synchronization interval.
191
     *
192
     * @param syncInterval New synchronization interval in minutes.
193
     */
194
    public void setSyncInterval(int syncInterval);
195
196
    public void addPropertyChangeListener(PropertyChangeListener listener);
197
198
    public void removePropertyChangeListener(PropertyChangeListener listener);
199
200
    /**
141
     * Class holding info about Hudson instance persistence.
201
     * Class holding info about Hudson instance persistence.
142
     *
202
     *
143
     * @author jhavlin
203
     * @author jhavlin
(-)a/hudson/src/org/netbeans/modules/hudson/api/HudsonJob.java (-1 lines)
Lines 49-55 Link Here
49
import java.util.logging.Logger;
49
import java.util.logging.Logger;
50
import org.netbeans.api.annotations.common.NonNull;
50
import org.netbeans.api.annotations.common.NonNull;
51
import org.openide.filesystems.FileSystem;
51
import org.openide.filesystems.FileSystem;
52
import org.openide.nodes.AbstractNode;
53
52
54
/**
53
/**
55
 * Instance of the Hudson Job in specified instance
54
 * Instance of the Hudson Job in specified instance
(-)a/hudson/src/org/netbeans/modules/hudson/api/HudsonJobBuild.java (+29 lines)
Lines 43-48 Link Here
43
package org.netbeans.modules.hudson.api;
43
package org.netbeans.modules.hudson.api;
44
44
45
import java.util.Collection;
45
import java.util.Collection;
46
import org.netbeans.modules.hudson.spi.ConsoleDataDisplayerImpl;
47
import org.netbeans.modules.hudson.spi.FailureDataDisplayerImpl;
46
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
48
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
47
import org.netbeans.modules.hudson.spi.HudsonSCM;
49
import org.netbeans.modules.hudson.spi.HudsonSCM;
48
import org.openide.filesystems.FileSystem;
50
import org.openide.filesystems.FileSystem;
Lines 89-92 Link Here
89
     */
91
     */
90
    String getDisplayName();
92
    String getDisplayName();
91
93
94
    /**
95
     * Check whether build console is supported by this build.
96
     *
97
     * @return True if the build console can be shown, false otherwise.
98
     */
99
    boolean canShowConsole();
100
101
    /**
102
     * Show console data using a displayer.
103
     *
104
     * @param displayer Displayer capable to display the console data.
105
     */
106
    void showConsole(ConsoleDataDisplayerImpl displayer);
107
108
    /**
109
     * Check whether build failures are supported by this build.
110
     *
111
     * @return True if build failures can be shown, false otherwise.
112
     */
113
    boolean canShowFailures();
114
115
    /**
116
     * Show build failures using a displayer.
117
     *
118
     * @param displayer Displayer capable to display the failure data.
119
     */
120
    void showFailures(FailureDataDisplayerImpl displayer);
92
}
121
}
(-)a/hudson/src/org/netbeans/modules/hudson/api/HudsonManager.java (+47 lines)
Lines 42-47 Link Here
42
42
43
package org.netbeans.modules.hudson.api;
43
package org.netbeans.modules.hudson.api;
44
44
45
import java.util.Collection;
45
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
46
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
46
import org.netbeans.modules.hudson.api.HudsonInstance.Persistence;
47
import org.netbeans.modules.hudson.api.HudsonInstance.Persistence;
47
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
48
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
Lines 143-146 Link Here
143
            ((HudsonInstanceImpl) instance).synchronize(false);
144
            ((HudsonInstanceImpl) instance).synchronize(false);
144
        }
145
        }
145
    }
146
    }
147
148
    /**
149
     * Get an instance with specified URL.
150
     *
151
     * @param url URL of the instance.
152
     * @return The instance whose url equals to parameter {@code url}, or null
153
     * if no such instance exists.
154
     */
155
    public static HudsonInstance getInstance(String url) {
156
        return HudsonManagerImpl.getDefault().getInstance(url);
157
    }
158
159
    public static HudsonInstance getInstanceByName(String name) {
160
        return HudsonManagerImpl.getDefault().getInstanceByName(name);
161
    }
162
163
    /**
164
     * Get all registered instances.
165
     *
166
     * @return A collection containing all registered instances.
167
     */
168
    public static Collection<? extends HudsonInstance> getAllInstances() {
169
        return HudsonManagerImpl.getDefault().getInstances();
170
    }
171
172
    /**
173
     * Simplify server location. Remove protocol, and if {@code forKey} is true,
174
     * also replace slashes and colons with underscores.
175
     *
176
     * @param name Server name, usually a URL.
177
     * @param forKey True if the result will be used for key (slashes and colons
178
     * will be replaced with underscores), false otherwise (only protocol part
179
     * of the URL and the ending slash will be removed).
180
     * @return Simplified server location.
181
     */
182
    public static String simplifyServerLocation(String name, boolean forKey) {
183
        return HudsonManagerImpl.simplifyServerLocation(name, forKey);
184
    }
185
186
    public static void addHudsonChangeListener(HudsonChangeListener listener) {
187
        HudsonManagerImpl.getDefault().addHudsonChangeListener(listener);
188
    }
189
190
    public static void removeHudsonChangeListener(HudsonChangeListener listener) {
191
        HudsonManagerImpl.getDefault().removeHudsonChangeListener(listener);
192
    }
146
}
193
}
(-)a/hudson/src/org/netbeans/modules/hudson/api/HudsonMavenModuleBuild.java (+29 lines)
Lines 43-48 Link Here
43
package org.netbeans.modules.hudson.api;
43
package org.netbeans.modules.hudson.api;
44
44
45
import org.netbeans.modules.hudson.api.HudsonJob.Color;
45
import org.netbeans.modules.hudson.api.HudsonJob.Color;
46
import org.netbeans.modules.hudson.spi.ConsoleDataDisplayerImpl;
47
import org.netbeans.modules.hudson.spi.FailureDataDisplayerImpl;
46
import org.openide.filesystems.FileSystem;
48
import org.openide.filesystems.FileSystem;
47
49
48
/**
50
/**
Lines 86-89 Link Here
86
     */
88
     */
87
    String getBuildDisplayName();
89
    String getBuildDisplayName();
88
90
91
    /**
92
     * Check whether build console is supported by this module build.
93
     *
94
     * @return True if the build console can be shown, false otherwise.
95
     */
96
    boolean canShowConsole();
97
98
    /**
99
     * Show console data using a displayer.
100
     *
101
     * @param displayer Displayer capable to display the console data.
102
     */
103
    void showConsole(ConsoleDataDisplayerImpl displayer);
104
105
    /**
106
     * Check whether build failures are supported by this module build.
107
     *
108
     * @return True if build failures can be shown, false otherwise.
109
     */
110
    boolean canShowFailures();
111
112
    /**
113
     * Show build failures using a displayer.
114
     *
115
     * @param displayer Displayer capable to display the failure data.
116
     */
117
    void showFailures(FailureDataDisplayerImpl displayer);
89
}
118
}
(-)a/hudson/src/org/netbeans/modules/hudson/api/Utilities.java (-1 / +43 lines)
Lines 51-57 Link Here
51
import javax.xml.xpath.XPath;
51
import javax.xml.xpath.XPath;
52
import javax.xml.xpath.XPathExpressionException;
52
import javax.xml.xpath.XPathExpressionException;
53
import javax.xml.xpath.XPathFactory;
53
import javax.xml.xpath.XPathFactory;
54
import org.netbeans.modules.hudson.api.HudsonVersion;
54
import org.netbeans.modules.hudson.Installer;
55
import static org.netbeans.modules.hudson.api.HudsonJobBuild.Result.FAILURE;
56
import static org.netbeans.modules.hudson.api.HudsonJobBuild.Result.SUCCESS;
57
import static org.netbeans.modules.hudson.api.HudsonJobBuild.Result.UNSTABLE;
58
import org.netbeans.modules.hudson.impl.HudsonInstanceImpl;
55
import org.openide.util.Parameters;
59
import org.openide.util.Parameters;
56
import org.w3c.dom.Element;
60
import org.w3c.dom.Element;
57
61
Lines 116-119 Link Here
116
        }
120
        }
117
        private static final XPath xpath = XPathFactory.newInstance().newXPath();
121
        private static final XPath xpath = XPathFactory.newInstance().newXPath();
118
122
123
    /**
124
     * Quickly check whether Hudson support is in use.
125
     *
126
     * @return True if Hudson support is in use, false otherwise.
127
     */
128
    public static boolean isHudsonSupportActive() {
129
        return Installer.active();
130
    }
131
132
    /**
133
     * Make an instance persistent.
134
     *
135
     * @param instance Hudson instance to persist.
136
     */
137
    public static void persistInstance(HudsonInstance instance) {
138
        if (instance instanceof HudsonInstanceImpl) {
139
            ((HudsonInstanceImpl) instance).makePersistent();
140
        }
141
    }
142
143
    /**
144
     * Get appropriate {@link HudsonJob.Color} instance for a build.
145
     *
146
     * @param build Hudson Job Build.
147
     * @return Appropriate color, depending on the result of the build.
148
     */
149
    public static HudsonJob.Color getColorForBuild(HudsonJobBuild build) {
150
        switch (build.getResult()) {
151
            case SUCCESS:
152
                return HudsonJob.Color.blue;
153
            case UNSTABLE:
154
                return HudsonJob.Color.yellow;
155
            case FAILURE:
156
                return HudsonJob.Color.red;
157
            default:
158
                return HudsonJob.Color.grey;
159
        }
160
    }
119
}
161
}
(-)a/hudson/src/org/netbeans/modules/hudson/api/ui/ConsoleDataDisplayer.java (+79 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.hudson.api.ui;
43
44
import org.netbeans.modules.hudson.api.HudsonJobBuild;
45
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
46
import org.netbeans.modules.hudson.spi.BuilderConnector.ConsoleDataProvider;
47
import org.netbeans.modules.hudson.spi.ConsoleDataDisplayerImpl;
48
49
/**
50
 * Displayer of console data. Insances of this class will be passed to
51
 * {@link ConsoleDataProvider#showConsole(HudsonJobBuild, ConsoleDataDisplayer)}
52
 * and
53
 * {@link ConsoleDataProvider#showConsole(HudsonMavenModuleBuild, ConsoleDataDisplayer)}.
54
 *
55
 * Do not implement this interface in your classes. Use
56
 * {@link ConsoleDataDisplayerImpl} instead.
57
 *
58
 * @author jhavlin
59
 */
60
public interface ConsoleDataDisplayer {
61
62
    /**
63
     * Prepare the console displayer for writing, initilize needed resources.
64
     */
65
    void open();
66
67
    /**
68
     * Write one line to the console.
69
     *
70
     * @param line Line of console output.
71
     * @return True if writing was successfull, false otherwise.
72
     */
73
    boolean writeLine(String line);
74
75
    /**
76
     * Finish writing to the console displayer, close all resources.
77
     */
78
    void close();
79
}
(-)a/hudson/src/org/netbeans/modules/hudson/api/ui/FailureDataDisplayer.java (+175 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.hudson.api.ui;
43
44
import java.util.ArrayList;
45
import java.util.List;
46
import org.netbeans.modules.hudson.api.HudsonJobBuild;
47
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
48
import org.netbeans.modules.hudson.spi.BuilderConnector.FailureDataProvider;
49
import org.netbeans.modules.hudson.spi.FailureDataDisplayerImpl;
50
51
/**
52
 * Displayer of failure data. Instances of this class will be passed to
53
 * {@link FailureDataProvider#showFailures(HudsonJobBuild, FailureDataDisplayer)}
54
 * and
55
 * {@link FailureDataProvider#showFailures(HudsonMavenModuleBuild, FailureDataDisplayer)}.
56
 *
57
 * Do not implement this interface in your classes. Use
58
 * {@link FailureDataDisplayerImpl} instead.
59
 *
60
 * @author jhavlin
61
 */
62
public interface FailureDataDisplayer {
63
64
    /**
65
     * Prepare the displayer for writing. Prepare needed resources.
66
     */
67
    void open();
68
69
    /**
70
     * Show a test suite.
71
     *
72
     * @param suite Test suite data.
73
     */
74
    void showSuite(Suite suite);
75
76
    /**
77
     * Finish writing to the displayer. Close all resources.
78
     */
79
    void close();
80
81
    /**
82
     * Info about failed test suite.
83
     */
84
    public static final class Suite {
85
86
        private String name;
87
        private String stdout;
88
        private String stderr;
89
        private long duration;
90
        private final List<Case> cases = new ArrayList<Case>();
91
92
        public String getName() {
93
            return name;
94
        }
95
96
        public String getStdout() {
97
            return stdout;
98
        }
99
100
        public String getStderr() {
101
            return stderr;
102
        }
103
104
        public long getDuration() {
105
            return duration;
106
        }
107
108
        public void setName(String name) {
109
            this.name = name;
110
        }
111
112
        public void setStdout(String stdout) {
113
            this.stdout = stdout;
114
        }
115
116
        public void setStderr(String stderr) {
117
            this.stderr = stderr;
118
        }
119
120
        public void setDuration(long duration) {
121
            this.duration = duration;
122
        }
123
124
        public List<Case> getCases() {
125
            return cases;
126
        }
127
128
        public void addCase(Case cs) {
129
            cases.add(cs);
130
        }
131
    }
132
133
    /**
134
     * Info about failed test case.
135
     */
136
    public static final class Case {
137
138
        private String className;
139
        private String name;
140
        private String errorStackTrace;
141
        private long duration;
142
143
        public String getClassName() {
144
            return className;
145
        }
146
147
        public String getName() {
148
            return name;
149
        }
150
151
        public String getErrorStackTrace() {
152
            return errorStackTrace;
153
        }
154
155
        public long getDuration() {
156
            return duration;
157
        }
158
159
        public void setClassName(String className) {
160
            this.className = className;
161
        }
162
163
        public void setName(String name) {
164
            this.name = name;
165
        }
166
167
        public void setErrorStackTrace(String errorStackTrace) {
168
            this.errorStackTrace = errorStackTrace;
169
        }
170
171
        public void setDuration(long duration) {
172
            this.duration = duration;
173
        }
174
    }
175
}
(-)a/hudson/src/org/netbeans/modules/hudson/ui/interfaces/OpenableInBrowser.java (-1 / +1 lines)
Lines 42-48 Link Here
42
 * made subject to such option by the copyright holder.
42
 * made subject to such option by the copyright holder.
43
 */
43
 */
44
44
45
package org.netbeans.modules.hudson.ui.interfaces;
45
package org.netbeans.modules.hudson.api.ui;
46
46
47
/**
47
/**
48
 * Marks objects that can be open in browser
48
 * Marks objects that can be open in browser
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonConnector.java (-6 / +6 lines)
Lines 93-102 Link Here
93
 */
93
 */
94
public class HudsonConnector extends BuilderConnector {
94
public class HudsonConnector extends BuilderConnector {
95
    private static final Logger LOG = Logger.getLogger(HudsonConnector.class.getName());
95
    private static final Logger LOG = Logger.getLogger(HudsonConnector.class.getName());
96
    public static final HudsonFailureDisplayer HUDSON_FAILURE_DISPLAYER =
96
    public static final HudsonFailureDataProvider HUDSON_FAILURE_DISPLAYER =
97
            new HudsonFailureDisplayer();
97
            new HudsonFailureDataProvider();
98
    public static final HudsonConsoleDisplayer HUDSON_CONSOLE_DISPLAYER =
98
    public static final HudsonConsoleDataProvider HUDSON_CONSOLE_DISPLAYER =
99
            new HudsonConsoleDisplayer();
99
            new HudsonConsoleDataProvider();
100
    
100
    
101
    private HudsonVersion version;
101
    private HudsonVersion version;
102
    private boolean connected = false;
102
    private boolean connected = false;
Lines 567-578 Link Here
567
    }
567
    }
568
568
569
    @Override
569
    @Override
570
    public ConsoleDisplayer getConsoleDisplayer() {
570
    public ConsoleDataProvider getConsoleDataProvider() {
571
        return HUDSON_CONSOLE_DISPLAYER;
571
        return HUDSON_CONSOLE_DISPLAYER;
572
    }
572
    }
573
573
574
    @Override
574
    @Override
575
    public FailureDisplayer getFailureDisplayer() {
575
    public FailureDataProvider getFailureDataProvider() {
576
        return HUDSON_FAILURE_DISPLAYER;
576
        return HUDSON_FAILURE_DISPLAYER;
577
    }
577
    }
578
578
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonConsoleDisplayer.java (-26 / +23 lines)
Lines 49-107 Link Here
49
import java.util.logging.Level;
49
import java.util.logging.Level;
50
import java.util.logging.Logger;
50
import java.util.logging.Logger;
51
import java.util.zip.GZIPInputStream;
51
import java.util.zip.GZIPInputStream;
52
import javax.swing.Action;
53
import org.netbeans.modules.hudson.api.ConnectionBuilder;
52
import org.netbeans.modules.hudson.api.ConnectionBuilder;
54
import org.netbeans.modules.hudson.api.HudsonInstance;
53
import org.netbeans.modules.hudson.api.HudsonInstance;
55
import org.netbeans.modules.hudson.api.HudsonJob;
54
import org.netbeans.modules.hudson.api.HudsonJob;
56
import org.netbeans.modules.hudson.api.HudsonJobBuild;
55
import org.netbeans.modules.hudson.api.HudsonJobBuild;
57
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
56
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
57
import org.netbeans.modules.hudson.api.ui.ConsoleDataDisplayer;
58
import org.netbeans.modules.hudson.spi.BuilderConnector;
58
import org.netbeans.modules.hudson.spi.BuilderConnector;
59
import org.netbeans.modules.hudson.ui.actions.Hyperlinker;
60
import org.openide.util.RequestProcessor;
59
import org.openide.util.RequestProcessor;
61
import org.openide.windows.IOProvider;
62
import org.openide.windows.InputOutput;
63
import org.openide.windows.OutputWriter;
64
60
65
/**
61
/**
66
 *
62
 *
67
 * @author jhavlin
63
 * @author jhavlin
68
 */
64
 */
69
public class HudsonConsoleDisplayer extends BuilderConnector.ConsoleDisplayer {
65
public class HudsonConsoleDataProvider extends BuilderConnector.ConsoleDataProvider {
70
66
71
    private static final Logger LOG = Logger.getLogger(
67
    private static final Logger LOG = Logger.getLogger(
72
            HudsonConsoleDisplayer.class.getName());
68
            HudsonConsoleDataProvider.class.getName());
69
    private boolean stopped = false;
73
70
74
    @Override
71
    @Override
75
    public void showConsole(final HudsonJobBuild build) {
72
    public void showConsole(final HudsonJobBuild build,
73
            final ConsoleDataDisplayer displayer) {
76
        new RequestProcessor(build.getUrl() + "console").post( //NOI18N
74
        new RequestProcessor(build.getUrl() + "console").post( //NOI18N
77
                new Runnable() {
75
                new Runnable() {
78
            @Override
76
            @Override
79
            public void run() {
77
            public void run() {
80
                showBuildConsole(build.getJob(), build.getUrl(),
78
                showBuildConsole(build.getJob(), build.getUrl(),
81
                        build.getDisplayName());
79
                        build.getDisplayName(), displayer);
82
            }
80
            }
83
        });
81
        });
84
    }
82
    }
85
83
86
    @Override
84
    @Override
87
    public void showConsole(final HudsonMavenModuleBuild moduleBuild) {
85
    public void showConsole(final HudsonMavenModuleBuild moduleBuild,
86
            final ConsoleDataDisplayer displayer) {
88
        new RequestProcessor(moduleBuild.getUrl() + "console").post( //NOI18N
87
        new RequestProcessor(moduleBuild.getUrl() + "console").post( //NOI18N
89
                new Runnable() {
88
                new Runnable() {
90
            @Override
89
            @Override
91
            public void run() {
90
            public void run() {
92
                showBuildConsole(moduleBuild.getBuild().getJob(),
91
                showBuildConsole(moduleBuild.getBuild().getJob(),
93
                        moduleBuild.getUrl(), moduleBuild.getDisplayName());
92
                        moduleBuild.getUrl(), moduleBuild.getDisplayName(),
93
                        displayer);
94
            }
94
            }
95
        });
95
        });
96
    }
96
    }
97
97
98
    @org.netbeans.api.annotations.common.SuppressWarnings(value = "OS_OPEN_STREAM")
98
    @org.netbeans.api.annotations.common.SuppressWarnings(value = "OS_OPEN_STREAM")
99
    @java.lang.SuppressWarnings(value = "SleepWhileInLoop")
99
    @java.lang.SuppressWarnings(value = "SleepWhileInLoop")
100
    public void showBuildConsole(HudsonJob job, String url, String displayName) {
100
    public void showBuildConsole(HudsonJob job, String url, String displayName,
101
        Hyperlinker hyperlinker = new Hyperlinker(job);
101
            ConsoleDataDisplayer displayer) {
102
102
        LOG.log(Level.FINE, "{0} started", url);                        //NOI18N
103
        LOG.log(Level.FINE, "{0} started", url);                        //NOI18N
103
        InputOutput io = IOProvider.getDefault().getIO(displayName, new Action[]{});
104
        displayer.open();
104
        io.select();
105
        /* If any metadata is needed, e.g. whether it is running, could use:
105
        /* If any metadata is needed, e.g. whether it is running, could use:
106
         HudsonJobBuild build = instance.getConnector().getJobBuild(job, buildNumber);
106
         HudsonJobBuild build = instance.getConnector().getJobBuild(job, buildNumber);
107
         if (build == null) {
107
         if (build == null) {
Lines 110-125 Link Here
110
         */
110
         */
111
        int start = 0;
111
        int start = 0;
112
        String urlPrefix = url + "progressiveLog?start=";               //NOI18N
112
        String urlPrefix = url + "progressiveLog?start=";               //NOI18N
113
        OutputWriter out = io.getOut();
114
        OutputWriter err = io.getErr();
115
        boolean running = job.getLastBuild() > job.getLastCompletedBuild(); // XXX should also check that this is in fact the current build
113
        boolean running = job.getLastBuild() > job.getLastCompletedBuild(); // XXX should also check that this is in fact the current build
116
        try {
114
        try {
117
            while (true) {
115
            while (!stopped) {
118
                LOG.log(Level.FINE, "{0} polling", url);                //NOI18N
116
                LOG.log(Level.FINE, "{0} polling", url);                //NOI18N
119
                if (out.checkError() || err.checkError() || io.isClosed()) {
120
                    LOG.log(Level.FINE, "{0} stopped", url);            //NOI18N
121
                    break;
122
                }
123
                URLConnection conn = new ConnectionBuilder().job(job).url(urlPrefix + start).header("Accept-Encoding", "gzip").connection(); //NOI18N
117
                URLConnection conn = new ConnectionBuilder().job(job).url(urlPrefix + start).header("Accept-Encoding", "gzip").connection(); //NOI18N
124
                boolean moreData = Boolean.parseBoolean(conn.getHeaderField("X-More-Data")); // NOI18N
118
                boolean moreData = Boolean.parseBoolean(conn.getHeaderField("X-More-Data")); // NOI18N
125
                LOG.log(Level.FINE, "{0} retrieving text from {1}", new Object[]{url, start});
119
                LOG.log(Level.FINE, "{0} retrieving text from {1}", new Object[]{url, start});
Lines 135-142 Link Here
135
                    BufferedReader r = new BufferedReader(new InputStreamReader(isToUse, "UTF-8")); //NOI18N
129
                    BufferedReader r = new BufferedReader(new InputStreamReader(isToUse, "UTF-8")); //NOI18N
136
                    String line;
130
                    String line;
137
                    while ((line = r.readLine()) != null) {
131
                    while ((line = r.readLine()) != null) {
138
                        OutputWriter stream = line.matches("(?i).*((warn(ing)?|err(or)?)[]:]|failed).*") ? err : out; //NOI18N
132
                        boolean success = displayer.writeLine(line);
139
                        hyperlinker.handleLine(line, stream);
133
                        if (!success) {
134
                            LOG.log(Level.FINE, "{0} stopped", url);    //NOI18N
135
                            stopped = true;
136
                            break;
137
                        }
140
                    }
138
                    }
141
                } finally {
139
                } finally {
142
                    is.close();
140
                    is.close();
Lines 162-168 Link Here
162
        } catch (IOException x) {
160
        } catch (IOException x) {
163
            LOG.log(Level.INFO, null, x);
161
            LOG.log(Level.INFO, null, x);
164
        }
162
        }
165
        out.close();
163
        displayer.close();
166
        err.close();
167
    }
164
    }
168
}
165
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonFailureDisplayer.java (-271 / +48 lines)
Lines 42-89 Link Here
42
package org.netbeans.modules.hudson.impl;
42
package org.netbeans.modules.hudson.impl;
43
43
44
import java.awt.Toolkit;
44
import java.awt.Toolkit;
45
import java.awt.event.ActionEvent;
46
import java.io.FileNotFoundException;
45
import java.io.FileNotFoundException;
47
import java.io.IOException;
48
import java.util.ArrayList;
49
import java.util.List;
50
import java.util.Stack;
51
import java.util.logging.Level;
46
import java.util.logging.Level;
52
import java.util.logging.Logger;
47
import java.util.logging.Logger;
53
import java.util.regex.Matcher;
54
import java.util.regex.Pattern;
55
import javax.swing.AbstractAction;
56
import javax.swing.Action;
57
import org.netbeans.api.java.classpath.GlobalPathRegistry;
58
import org.netbeans.api.project.Project;
59
import org.netbeans.modules.gsf.testrunner.api.CallstackFrameNode;
60
import org.netbeans.modules.gsf.testrunner.api.DiffViewAction;
61
import org.netbeans.modules.gsf.testrunner.api.Manager;
62
import org.netbeans.modules.gsf.testrunner.api.TestMethodNode;
63
import org.netbeans.modules.gsf.testrunner.api.TestRunnerNodeFactory;
64
import org.netbeans.modules.gsf.testrunner.api.TestSession;
65
import org.netbeans.modules.gsf.testrunner.api.TestSuite;
66
import org.netbeans.modules.gsf.testrunner.api.Testcase;
67
import org.netbeans.modules.gsf.testrunner.api.TestsuiteNode;
68
import org.netbeans.modules.gsf.testrunner.api.Trouble;
69
import org.netbeans.modules.hudson.api.ConnectionBuilder;
48
import org.netbeans.modules.hudson.api.ConnectionBuilder;
70
import org.netbeans.modules.hudson.api.HudsonJob;
49
import org.netbeans.modules.hudson.api.HudsonJob;
71
import org.netbeans.modules.hudson.api.HudsonJobBuild;
50
import org.netbeans.modules.hudson.api.HudsonJobBuild;
72
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
51
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
52
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer;
53
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer.Case;
54
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer.Suite;
73
import org.netbeans.modules.hudson.spi.BuilderConnector;
55
import org.netbeans.modules.hudson.spi.BuilderConnector;
74
import org.netbeans.modules.hudson.spi.HudsonLogger;
75
import org.netbeans.modules.hudson.ui.actions.Hyperlinker;
76
import org.netbeans.modules.hudson.ui.actions.OpenUrlAction;
77
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
78
import org.openide.awt.StatusDisplayer;
56
import org.openide.awt.StatusDisplayer;
79
import org.openide.filesystems.FileObject;
80
import org.openide.filesystems.FileUtil;
81
import org.openide.util.Lookup;
82
import org.openide.util.NbBundle;
57
import org.openide.util.NbBundle;
83
import org.openide.util.RequestProcessor;
58
import org.openide.util.RequestProcessor;
84
import org.openide.windows.IOProvider;
85
import org.openide.windows.InputOutput;
86
import org.openide.windows.OutputWriter;
87
import org.openide.xml.XMLUtil;
59
import org.openide.xml.XMLUtil;
88
import org.xml.sax.Attributes;
60
import org.xml.sax.Attributes;
89
import org.xml.sax.InputSource;
61
import org.xml.sax.InputSource;
Lines 95-149 Link Here
95
 *
67
 *
96
 * @author jhavlin
68
 * @author jhavlin
97
 */
69
 */
98
public class HudsonFailureDisplayer extends BuilderConnector.FailureDisplayer {
70
@NbBundle.Messages({
71
    "no_test_result=No test result found for this build."})
72
public class HudsonFailureDataProvider extends BuilderConnector.FailureDataProvider {
99
73
100
    private static final Logger LOG = Logger.getLogger(
74
    private static final Logger LOG = Logger.getLogger(
101
            HudsonFailureDisplayer.class.getName());
75
            HudsonFailureDataProvider.class.getName());
102
    private static final RequestProcessor RP = new RequestProcessor(
103
            HudsonFailureDisplayer.class);
104
    private static final Pattern ASSERTION_FAILURE = Pattern.compile(
105
            "(?m)junit[.]framework[.](AssertionFailedError|(Array)?ComparisonFailure)|java[.]lang[.]AssertionError($|: )"); //NOI18N
106
76
107
    @Override
77
    @Override
108
    public void showFailures(final HudsonJobBuild build) {
78
    public void showFailures(final HudsonJobBuild build,
79
            final FailureDataDisplayer displayer) {
109
        new RequestProcessor(build.getUrl() + "failures").post( // NOI18N
80
        new RequestProcessor(build.getUrl() + "failures").post( // NOI18N
110
                new Runnable() {
81
                new Runnable() {
111
            @Override
82
            @Override
112
            public void run() {
83
            public void run() {
113
                showBuildFailures(build.getJob(), build.getUrl(),
84
                showBuildFailures(build.getJob(), build.getUrl(), displayer);
114
                        build.getDisplayName());
115
            }
85
            }
116
        });
86
        });
117
    }
87
    }
118
88
119
    @Override
89
    @Override
120
    public void showFailures(final HudsonMavenModuleBuild moduleBuild) {
90
    public void showFailures(final HudsonMavenModuleBuild moduleBuild,
91
            final FailureDataDisplayer displayer) {
121
        new RequestProcessor(moduleBuild.getUrl() + "failures").post( // NOI18N
92
        new RequestProcessor(moduleBuild.getUrl() + "failures").post( // NOI18N
122
                new Runnable() {
93
                new Runnable() {
123
            @Override
94
            @Override
124
            public void run() {
95
            public void run() {
125
                showBuildFailures(
96
                showBuildFailures(moduleBuild.getBuild().getJob(),
126
                        moduleBuild.getBuild().getJob(), moduleBuild.getUrl(),
97
                        moduleBuild.getUrl(), displayer);
127
                        moduleBuild.getBuildDisplayName());
128
            }
98
            }
129
        });
99
        });
130
    }
100
    }
131
101
132
    @NbBundle.Messages({
102
    private void showBuildFailures(HudsonJob job, String url,
133
        "# {0} - job #build", "ShowFailures.title={0} Test Failures",
103
            FailureDataDisplayer displayer) {
134
        "# {0} - class & method name of failed test", "# {1} - suite name of failed test", "ShowFailures.from_suite={0} (from {1})",
104
135
        "LBL_GotoSource=Go to Source",
136
        "no_test_result=No test result found for this build.",
137
        "# {0} - Java source file resource path", "no_source_to_hyperlink=Could not find {0} among open projects."
138
    })
139
    public void showBuildFailures(HudsonJob job, String url, String displayName) {
140
        try {
105
        try {
141
            XMLReader parser = XMLUtil.createXMLReader();
106
            XMLReader parser = XMLUtil.createXMLReader();
142
            parser.setContentHandler(new ContentHandler(job, url, displayName));
107
            parser.setContentHandler(new ContentHandler(displayer));
143
            // XXX could use ?tree (would be faster) if there were an alternate object for failed tests only
108
            // XXX could use ?tree (would be faster) if there were an alternate object for failed tests only
144
            String u = url + "testReport/api/xml?xpath=//suite[case/errorStackTrace]&wrapper=failures"; //NOI18N
109
            String u = url + "testReport/api/xml?xpath=//suite[case/errorStackTrace]&wrapper=failures"; //NOI18N
145
            InputSource source = new InputSource(new ConnectionBuilder().job(job).url(u).connection().getInputStream());
110
            InputSource source = new InputSource(new ConnectionBuilder().job(job).url(u).connection().getInputStream());
146
            source.setSystemId(u);
111
            source.setSystemId(u);
112
            displayer.open();
147
            parser.parse(source);
113
            parser.parse(source);
148
        } catch (FileNotFoundException x) {
114
        } catch (FileNotFoundException x) {
149
            Toolkit.getDefaultToolkit().beep();
115
            Toolkit.getDefaultToolkit().beep();
Lines 156-221 Link Here
156
122
157
    private class ContentHandler extends DefaultHandler {
123
    private class ContentHandler extends DefaultHandler {
158
124
159
        public ContentHandler(HudsonJob job, String url, String displayName) {
125
        private StringBuilder buf;
160
            this.url = url;
126
        private final FailureDataDisplayer displayer;
161
            this.displayName = displayName;
162
            this.hyperlinker = new Hyperlinker(job);
163
            this.session = createTestSession(displayName);
164
        }
165
        private String url;
166
        private String displayName;
167
        InputOutput io;
168
        StringBuilder buf;
169
        Hyperlinker hyperlinker;
170
        TestSession session;
171
        Project project;
172
127
173
        private TestSession createTestSession(String displayName) {
128
        public ContentHandler(FailureDataDisplayer displayer) {
174
129
            this.displayer = displayer;
175
            // Store reference to project here, as reference in test session
176
            // is weak.
177
            this.project = new Project() {
178
                public @Override
179
                FileObject getProjectDirectory() {
180
                    return FileUtil.createMemoryFileSystem().getRoot();
181
                }
182
183
                public @Override
184
                Lookup getLookup() {
185
                    return Lookup.EMPTY;
186
                }
187
            };
188
            TestRunnerNodeFactory testRunnerNodeFactory =
189
                    new HudsonTestRunnerNodeFactory();
190
            return new TestSession(displayName, project,
191
                    TestSession.SessionType.TEST, testRunnerNodeFactory);
192
        }
193
194
        private void prepareOutput() {
195
            if (io == null) {
196
                String title = Bundle.ShowFailures_title(displayName);
197
                io = IOProvider.getDefault().getIO(title, new Action[0]);
198
                io.select();
199
                Manager.getInstance().testStarted(session);
200
            }
201
        }
202
203
        class Suite {
204
205
            String name;
206
            String stdout;
207
            String stderr;
208
            Stack<Case> cases = new Stack<Case>();
209
            List<Case> casesDone = new ArrayList<Case>();
210
            long duration;
211
        }
212
213
        class Case {
214
215
            String className;
216
            String name;
217
            String errorStackTrace;
218
            long duration;
219
        }
130
        }
220
131
221
        long parseDuration(String d) {
132
        long parseDuration(String d) {
Lines 228-243 Link Here
228
                return 0;
139
                return 0;
229
            }
140
            }
230
        }
141
        }
231
        Stack<Suite> suites = new Stack<Suite>();
142
143
        Suite suite = null;
144
        Case caze = null;
232
145
233
        public @Override
146
        public @Override
234
        void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
147
        void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
235
            if (qName.matches("errorStackTrace|stdout|stderr|name|className")) { //NOI18N
148
            if (qName.matches("errorStackTrace|stdout|stderr|name|className")) { //NOI18N
236
                buf = new StringBuilder();
149
                buf = new StringBuilder();
237
            } else if (qName.equals("suite")) { //NOI18N
150
            } else if (qName.equals("suite")) { //NOI18N
238
                suites.push(new Suite());
151
                suite = new Suite();
239
            } else if (qName.equals("case") && !suites.empty()) { //NOI18N
152
                caze = null;
240
                suites.peek().cases.push(new Case());
153
            } else if (qName.equals("case") && suite != null) { //NOI18N
154
                caze = new Case();
241
            }
155
            }
242
        }
156
        }
243
157
Lines 250-434 Link Here
250
164
251
        public @Override
165
        public @Override
252
        void endElement(String uri, String localName, String qName) throws SAXException {
166
        void endElement(String uri, String localName, String qName) throws SAXException {
253
            if (suites.empty()) {
167
            if (suite == null) {
254
                return;
168
                return;
255
            }
169
            }
256
            Suite s = suites.peek();
257
            String text = buf != null && buf.length() > 0 ? buf.toString() : null;
170
            String text = buf != null && buf.length() > 0 ? buf.toString() : null;
258
            buf = null;
171
            buf = null;
259
            if (s.cases.empty()) { // suite level
172
            if (caze == null) { // suite level
260
                if (qName.equals("stdout")) { // NOI18N
173
                if (qName.equals("stdout")) { // NOI18N
261
                    s.stdout = text;
174
                    suite.setStdout(text);
262
                } else if (qName.equals("stderr")) { // NOI18N
175
                } else if (qName.equals("stderr")) { // NOI18N
263
                    s.stderr = text;
176
                    suite.setStderr(text);
264
                } else if (qName.equals("name")) { // NOI18N
177
                } else if (qName.equals("name")) { // NOI18N
265
                    s.name = text;
178
                    suite.setName(text);
266
                } else if (qName.equals("duration")) { // NOI18N
179
                } else if (qName.equals("duration")) { // NOI18N
267
                    s.duration = parseDuration(text);
180
                    suite.setDuration(parseDuration(text));
268
                }
181
                }
269
            } else { // case level
182
            } else { // case level
270
                Case c = s.cases.peek();
271
                if (qName.equals("errorStackTrace")) { // NOI18N
183
                if (qName.equals("errorStackTrace")) { // NOI18N
272
                    c.errorStackTrace = text;
184
                    caze.setErrorStackTrace(text);
273
                } else if (qName.equals("name")) { // NOI18N
185
                } else if (qName.equals("name")) { // NOI18N
274
                    c.name = text;
186
                    caze.setName(text);
275
                } else if (qName.equals("className")) { // NOI18N
187
                } else if (qName.equals("className")) { // NOI18N
276
                    c.className = text;
188
                    caze.setClassName(text);
277
                } else if (qName.equals("duration")) { // NOI18N
189
                } else if (qName.equals("duration")) { // NOI18N
278
                    c.duration = parseDuration(text);
190
                    caze.setDuration(parseDuration(text));
279
                }
191
                }
280
            }
192
            }
281
            if (qName.equals("suite")) { // NOI18N
193
            if (qName.equals("case")) { //NOI18N
194
                suite.addCase(caze);
195
                caze = null;
196
            } else if (qName.equals("suite")) { // NOI18N
282
                try {
197
                try {
283
                    show(s);
198
                    displayer.showSuite(suite);
284
                } catch (IOException x) {
199
                } catch (Exception x) {
285
                    LOG.log(Level.FINE, null, x);
200
                    LOG.log(Level.FINE, null, x);
286
                }
201
                }
287
                suites.pop();
202
                suite = null;
288
            } else if (qName.equals("case")) { // NOI18N
289
                s.casesDone.add(s.cases.pop());
290
            }
291
        }
292
293
        void show(Suite s) throws IOException {
294
            prepareOutput();
295
            OutputWriter out = io.getOut();
296
            OutputWriter err = io.getErr();
297
            TestSuite suite = new TestSuite(s.name);
298
            session.addSuite(suite);
299
            Manager.getInstance().displaySuiteRunning(session, suite.getName());
300
            if (s.stderr != null) {
301
                // XXX TR window does not seem to show only stdio from selected suite
302
                Manager.getInstance().displayOutput(session, s.stderr, true);
303
            }
304
            if (s.stdout != null) {
305
                Manager.getInstance().displayOutput(session, s.stdout, false);
306
            }
307
            for (final Case c : s.casesDone) {
308
                if (c.errorStackTrace == null) {
309
                    continue;
310
                }
311
                String name = c.className + "." + c.name; //NOI18N
312
                String shortName = c.name;
313
                if (s.name != null && !s.name.equals(c.className)) {
314
                    shortName = name;
315
                    name = Bundle.ShowFailures_from_suite(name, s.name);
316
                }
317
                println();
318
                out.println("[" + name + "]"); // XXX use color printing to make it stand out? //NOI18N
319
                show(c.errorStackTrace, /* err is too hard to read */ out);
320
                Testcase test = new Testcase(shortName, null, session);
321
                test.setClassName(c.className);
322
                Trouble trouble = new Trouble(!ASSERTION_FAILURE.matcher(c.errorStackTrace).lookingAt());
323
                trouble.setStackTrace(c.errorStackTrace.split("\r?\n")); //NOI18N
324
                // XXX call setComparisonFailure if matches "expected:<...> but was:<...>"
325
                test.setTrouble(trouble);
326
                LOG.log(Level.FINE, "got {0} as {1}", new Object[]{name, test.getStatus()}); //NOI18N
327
                test.setTimeMillis(c.duration);
328
                session.addTestCase(test);
329
            }
330
            if (s.stderr != null || s.stdout != null) {
331
                println();
332
                show(s.stderr, err);
333
                show(s.stdout, out);
334
            }
335
            Manager.getInstance().displayReport(session, session.getReport(s.duration));
336
        }
337
        boolean firstLine = true;
338
339
        void println() {
340
            if (firstLine) {
341
                firstLine = false;
342
            } else {
343
                io.getOut().println();
344
            }
345
        }
346
347
        void show(String lines, OutputWriter w) {
348
            if (lines == null) {
349
                return;
350
            }
351
            for (String line : lines.split("\r\n?|\n")) { //NOI18N
352
                hyperlinker.handleLine(line, w);
353
            }
203
            }
354
        }
204
        }
355
205
356
        @Override
206
        @Override
357
        public void endDocument() throws SAXException {
207
        public void endDocument() throws SAXException {
358
            if (io != null) {
208
            displayer.close();
359
                io.getOut().close();
360
                io.getErr().close();
361
                Manager.getInstance().sessionFinished(session);
362
            }
363
        }
364
365
        private class HudsonTestRunnerNodeFactory extends TestRunnerNodeFactory {
366
367
            public HudsonTestRunnerNodeFactory() {
368
            }
369
370
            public @Override
371
            TestsuiteNode createTestSuiteNode(String suiteName, boolean filtered) {
372
                // XXX could add OpenableInBrowser
373
                return new TestsuiteNode(suiteName, filtered);
374
            }
375
376
            public @Override
377
            org.openide.nodes.Node createTestMethodNode(final Testcase testcase,
378
                    Project project) {
379
                return new TestMethodNode(testcase, project) {
380
                    public @Override
381
                    Action[] getActions(boolean context) {
382
                        return new Action[]{
383
                                    OpenUrlAction.forOpenable(new OpenableInBrowser() {
384
                                public @Override
385
                                String getUrl() {
386
                                    return url + "testReport/"
387
                                            + testcase.getClassName().replaceFirst("[.][^.]+$", "") + "/" + testcase.getClassName().replaceFirst(".+[.]", "") + "/" + testcase.getName() + "/"; //NOI18N
388
                                }
389
                            }),
390
                                    new DiffViewAction(testcase),};
391
                    }
392
                };
393
            }
394
395
            public @Override
396
            org.openide.nodes.Node createCallstackFrameNode(String frameInfo, String displayName) {
397
                return new CallstackFrameNode(frameInfo, displayName) {
398
                    public @Override
399
                    Action getPreferredAction() {
400
                        return new AbstractAction(Bundle.LBL_GotoSource()) {
401
                            public @Override
402
                            void actionPerformed(ActionEvent e) {
403
                                // XXX should have utility API to parse stack traces
404
                                final Matcher m = Pattern.compile("\tat (.+[.])[^.]+[.][^.]+[(]([^.]+[.]java):([0-9]+)[)]").matcher(frameInfo); //NOI18N
405
                                if (m.matches()) {
406
                                    final String resource = m.group(1).replace('.', '/') + m.group(2);
407
                                    RP.post(new Runnable() {
408
                                        @Override
409
                                        public void run() {
410
                                            FileObject f = GlobalPathRegistry.getDefault().findResource(resource);
411
                                            LOG.log(Level.FINER, "matched {0} -> {1}", new Object[]{resource, f}); //NOI18N
412
                                            if (f != null) {
413
                                                HudsonLogger.Helper.openAt(f, Integer.parseInt(m.group(3)) - 1, -1, true);
414
                                            } else {
415
                                                StatusDisplayer.getDefault().setStatusText(Bundle.no_source_to_hyperlink(resource));
416
                                            }
417
                                        }
418
                                    });
419
                                } else {
420
                                    LOG.log(Level.FINER, "no match for {0}", frameInfo); //NOI18N
421
                                }
422
                            }
423
                        };
424
                    }
425
426
                    public @Override
427
                    Action[] getActions(boolean context) {
428
                        return new Action[]{getPreferredAction()};
429
                    }
430
                };
431
            }
432
        }
209
        }
433
    }
210
    }
434
}
211
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonFolderImpl.java (-1 / +1 lines)
Lines 48-55 Link Here
48
import org.netbeans.modules.hudson.api.HudsonFolder;
48
import org.netbeans.modules.hudson.api.HudsonFolder;
49
import org.netbeans.modules.hudson.api.HudsonInstance;
49
import org.netbeans.modules.hudson.api.HudsonInstance;
50
import org.netbeans.modules.hudson.api.HudsonJob;
50
import org.netbeans.modules.hudson.api.HudsonJob;
51
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
51
import org.netbeans.modules.hudson.spi.BuilderConnector;
52
import org.netbeans.modules.hudson.spi.BuilderConnector;
52
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
53
import org.openide.util.ChangeSupport;
53
import org.openide.util.ChangeSupport;
54
import org.openide.util.WeakListeners;
54
import org.openide.util.WeakListeners;
55
55
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonInstanceImpl.java (-17 / +44 lines)
Lines 63-69 Link Here
63
import org.netbeans.api.progress.ProgressHandle;
63
import org.netbeans.api.progress.ProgressHandle;
64
import org.netbeans.api.progress.ProgressHandleFactory;
64
import org.netbeans.api.progress.ProgressHandleFactory;
65
import org.netbeans.modules.hudson.api.ConnectionBuilder;
65
import org.netbeans.modules.hudson.api.ConnectionBuilder;
66
import org.netbeans.modules.hudson.api.HudsonChangeAdapter;
67
import org.netbeans.modules.hudson.api.HudsonChangeListener;
66
import org.netbeans.modules.hudson.api.HudsonChangeListener;
68
import org.netbeans.modules.hudson.api.HudsonFolder;
67
import org.netbeans.modules.hudson.api.HudsonFolder;
69
import org.netbeans.modules.hudson.api.HudsonInstance;
68
import org.netbeans.modules.hudson.api.HudsonInstance;
Lines 72-84 Link Here
72
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
71
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
73
import org.netbeans.modules.hudson.api.HudsonVersion;
72
import org.netbeans.modules.hudson.api.HudsonVersion;
74
import org.netbeans.modules.hudson.api.HudsonView;
73
import org.netbeans.modules.hudson.api.HudsonView;
74
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
75
import org.netbeans.modules.hudson.constants.HudsonInstanceConstants;
75
import org.netbeans.modules.hudson.constants.HudsonInstanceConstants;
76
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
76
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
77
import static org.netbeans.modules.hudson.constants.HudsonJobConstants.*;
77
import static org.netbeans.modules.hudson.constants.HudsonJobConstants.*;
78
import org.netbeans.modules.hudson.spi.BuilderConnector;
78
import org.netbeans.modules.hudson.spi.BuilderConnector;
79
import org.netbeans.modules.hudson.spi.RemoteFileSystem;
79
import org.netbeans.modules.hudson.spi.RemoteFileSystem;
80
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
81
import org.netbeans.modules.hudson.ui.notification.ProblemNotificationController;
82
import org.openide.filesystems.FileSystem;
80
import org.openide.filesystems.FileSystem;
83
import org.openide.filesystems.FileUtil;
81
import org.openide.filesystems.FileUtil;
84
import org.openide.util.Cancellable;
82
import org.openide.util.Cancellable;
Lines 113-119 Link Here
113
    private Collection<HudsonView> views = new ArrayList<HudsonView>();
111
    private Collection<HudsonView> views = new ArrayList<HudsonView>();
114
    private HudsonView primaryView;
112
    private HudsonView primaryView;
115
    private final Collection<HudsonChangeListener> listeners = new ArrayList<HudsonChangeListener>();
113
    private final Collection<HudsonChangeListener> listeners = new ArrayList<HudsonChangeListener>();
116
    private ProblemNotificationController problemNotificationController;
117
    /**
114
    /**
118
     * Must be kept here, not in {@link HudsonJobImpl}, because that is transient
115
     * Must be kept here, not in {@link HudsonJobImpl}, because that is transient
119
     * and this should persist across refreshes.
116
     * and this should persist across refreshes.
Lines 152-167 Link Here
152
                }
149
                }
153
            }
150
            }
154
        });
151
        });
155
        
156
        addHudsonChangeListener(new HudsonChangeAdapter() {
157
            @Override
158
            public void contentChanged() {
159
                if (problemNotificationController == null) {
160
                    problemNotificationController = new ProblemNotificationController(HudsonInstanceImpl.this);
161
                }
162
                problemNotificationController.updateNotifications();
163
            }
164
        });
165
    }
152
    }
166
153
167
    @Override public boolean isPersisted() {
154
    @Override public boolean isPersisted() {
Lines 230-238 Link Here
230
        // Fire changes
217
        // Fire changes
231
        fireStateChanges();
218
        fireStateChanges();
232
        fireContentChanges();
219
        fireContentChanges();
233
        if (problemNotificationController != null) {
234
            problemNotificationController.clearNotifications();
235
        }
236
    }
220
    }
237
    
221
    
238
    public BuilderConnector getBuilderConnector() {
222
    public BuilderConnector getBuilderConnector() {
Lines 332-337 Link Here
332
     * Will run asynchronously.
316
     * Will run asynchronously.
333
     * @param authentication to prompt for login if the anonymous user cannot even see the job list; set to true for explicit user gesture, false otherwise
317
     * @param authentication to prompt for login if the anonymous user cannot even see the job list; set to true for explicit user gesture, false otherwise
334
     */
318
     */
319
    @Override
335
    public void synchronize(final boolean authentication) {
320
    public void synchronize(final boolean authentication) {
336
        if (terminated) {
321
        if (terminated) {
337
            return;
322
            return;
Lines 593-596 Link Here
593
    public Persistence getPersistence() {
578
    public Persistence getPersistence() {
594
        return persistence;
579
        return persistence;
595
    }
580
    }
581
582
    @Override
583
    public List<String> getPreferredJobs() {
584
        String preferred = properties.get(INSTANCE_PREF_JOBS);
585
        if (preferred == null) {
586
            return null;
587
        } else {
588
            return HudsonInstanceProperties.split(preferred);
589
        }
590
    }
591
592
    @Override
593
    public void setPreferredJobs(List<String> preferredJobs) {
594
        if (preferredJobs == null) {
595
            properties.put(INSTANCE_PREF_JOBS, null);
596
        } else {
597
            properties.put(INSTANCE_PREF_JOBS,
598
                    HudsonInstanceProperties.join(preferredJobs));
599
        }
600
    }
601
602
    @Override
603
    public int getSyncInterval() {
604
        return Integer.parseInt(getProperties().get(
605
                HudsonInstanceConstants.INSTANCE_SYNC));
606
    }
607
608
    @Override
609
    public void setSyncInterval(int syncInterval) {
610
        getProperties().put(HudsonInstanceConstants.INSTANCE_SYNC,
611
                Integer.toString(syncInterval));
612
    }
613
614
    @Override
615
    public void addPropertyChangeListener(PropertyChangeListener listener) {
616
        getProperties().addPropertyChangeListener(listener);
617
    }
618
619
    @Override
620
    public void removePropertyChangeListener(PropertyChangeListener listener) {
621
        getProperties().removePropertyChangeListener(listener);
622
    }
596
}
623
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonInstanceProperties.java (-75 lines)
Lines 55-66 Link Here
55
import java.util.prefs.BackingStoreException;
55
import java.util.prefs.BackingStoreException;
56
import java.util.prefs.Preferences;
56
import java.util.prefs.Preferences;
57
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
57
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
58
import static org.netbeans.modules.hudson.impl.Bundle.*;
59
import org.openide.nodes.Node;
60
import org.openide.nodes.PropertySupport;
61
import org.openide.nodes.Sheet;
62
import org.openide.util.Exceptions;
58
import org.openide.util.Exceptions;
63
import org.openide.util.NbBundle.Messages;
64
import org.openide.util.RequestProcessor;
59
import org.openide.util.RequestProcessor;
65
60
66
/**
61
/**
Lines 70-76 Link Here
70
 */
65
 */
71
public class HudsonInstanceProperties extends HashMap<String,String> {
66
public class HudsonInstanceProperties extends HashMap<String,String> {
72
    
67
    
73
    private Sheet.Set set;
74
    private static final RequestProcessor RP = new RequestProcessor(
68
    private static final RequestProcessor RP = new RequestProcessor(
75
            HudsonInstanceProperties.class);
69
            HudsonInstanceProperties.class);
76
    
70
    
Lines 110-163 Link Here
110
        return pers == null || TRUE.equals(pers);
104
        return pers == null || TRUE.equals(pers);
111
    }
105
    }
112
106
113
    @Messages({
114
        "TXT_Instance_Prop_Name=Name",
115
        "DESC_Instance_Prop_Name=Hudson's instance name",
116
        "TXT_Instance_Prop_Url=URL",
117
        "DESC_Instance_Prop_Url=Hudson's instance URL",
118
        "TXT_Instance_Prop_Sync=Autosynchronization time",
119
        "DESC_Instance_Prop_Sync=Autosynchronization time in minutes (if it's 0 the autosynchronization is off)"
120
    })
121
    public Sheet.Set getSheetSet() {
122
        if (null == set) {
123
            set = Sheet.createPropertiesSet();
124
            
125
            // Set display name
126
            set.setDisplayName(get(INSTANCE_NAME));
127
            
128
            // Put properties in
129
            set.put(new Node.Property<?>[] {
130
                new HudsonInstanceProperty(INSTANCE_NAME,
131
                        TXT_Instance_Prop_Name(),
132
                        DESC_Instance_Prop_Name(),
133
                        true, false),
134
                        new HudsonInstanceProperty(INSTANCE_URL,
135
                        TXT_Instance_Prop_Url(),
136
                        DESC_Instance_Prop_Url(),
137
                        true, false),
138
                        new PropertySupport<Integer>(INSTANCE_SYNC, Integer.class,
139
                        TXT_Instance_Prop_Sync(),
140
                        DESC_Instance_Prop_Sync(),
141
                        true, true) {
142
                            @Override public Integer getValue() {
143
                                return Integer.valueOf(get(INSTANCE_SYNC));
144
                            }
145
                            @Override public void setValue(Integer val) {
146
                                if (val == null || val < 0) {
147
                                    throw new IllegalArgumentException();
148
                                }
149
                                put(INSTANCE_SYNC, val.toString());
150
                            }
151
                            public @Override boolean canWrite() {
152
                                return isPersisted();
153
                            }
154
                        }
155
            });
156
        }
157
        
158
        return set;
159
    }
160
    
161
    public void addPropertyChangeListener(PropertyChangeListener l) {
107
    public void addPropertyChangeListener(PropertyChangeListener l) {
162
        pcs.addPropertyChangeListener(l);
108
        pcs.addPropertyChangeListener(l);
163
    }
109
    }
Lines 170-196 Link Here
170
        return Arrays.asList(pcs.getPropertyChangeListeners());
116
        return Arrays.asList(pcs.getPropertyChangeListeners());
171
    }
117
    }
172
118
173
    private class HudsonInstanceProperty extends PropertySupport<String> {
174
        
175
        private String key;
176
        
177
        HudsonInstanceProperty(String key, String name, String desc, boolean read, boolean write) {
178
            super(key, String.class, name, desc, read, write);
179
            
180
            this.key = key;
181
        }
182
        
183
        @Override
184
        public void setValue(String value) {
185
            put(key, value);
186
        }
187
        
188
        @Override
189
        public String getValue() {
190
            return get(key);
191
        }
192
    }
193
194
    public static List<String> split(String prop) {
119
    public static List<String> split(String prop) {
195
        if (prop != null && prop.trim().length() > 0) {
120
        if (prop != null && prop.trim().length() > 0) {
196
            String[] escaped = prop.split("(?<!/)/(?!/)");              //NOI18N
121
            String[] escaped = prop.split("(?<!/)/(?!/)");              //NOI18N
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonJobBuildImpl.java (-28 / +101 lines)
Lines 44-77 Link Here
44
44
45
package org.netbeans.modules.hudson.impl;
45
package org.netbeans.modules.hudson.impl;
46
46
47
import java.io.IOException;
48
import java.util.ArrayList;
47
import java.util.ArrayList;
49
import org.netbeans.modules.hudson.api.HudsonJob.Color;
50
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
51
import org.netbeans.modules.hudson.impl.HudsonJobImpl.HudsonMavenModule;
52
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
53
import java.util.Collection;
48
import java.util.Collection;
54
import java.util.Collections;
55
import java.util.List;
49
import java.util.List;
56
import java.util.concurrent.atomic.AtomicBoolean;
50
import java.util.concurrent.atomic.AtomicBoolean;
57
import java.util.concurrent.atomic.AtomicReference;
51
import java.util.concurrent.atomic.AtomicReference;
58
import java.util.logging.Level;
59
import java.util.logging.Logger;
52
import java.util.logging.Logger;
60
import org.netbeans.modules.hudson.api.ConnectionBuilder;
61
import org.netbeans.modules.hudson.api.HudsonJob;
53
import org.netbeans.modules.hudson.api.HudsonJob;
54
import org.netbeans.modules.hudson.api.HudsonJob.Color;
62
import org.netbeans.modules.hudson.api.HudsonJobBuild;
55
import org.netbeans.modules.hudson.api.HudsonJobBuild;
63
import org.netbeans.modules.hudson.api.Utilities;
56
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
64
import org.netbeans.modules.hudson.spi.HudsonSCM;
57
import org.netbeans.modules.hudson.api.ui.ConsoleDataDisplayer;
65
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
58
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer;
59
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
60
import static org.netbeans.modules.hudson.impl.Bundle.*;
61
import org.netbeans.modules.hudson.impl.HudsonJobImpl.HudsonMavenModule;
62
import org.netbeans.modules.hudson.spi.BuilderConnector;
63
import org.netbeans.modules.hudson.spi.ConsoleDataDisplayerImpl;
64
import org.netbeans.modules.hudson.spi.FailureDataDisplayerImpl;
65
import org.netbeans.modules.hudson.spi.HudsonJobChangeItem;
66
import org.openide.filesystems.FileSystem;
66
import org.openide.filesystems.FileSystem;
67
import org.openide.util.Lookup;
68
import org.openide.util.NbBundle.Messages;
67
import org.openide.util.NbBundle.Messages;
69
import static org.netbeans.modules.hudson.impl.Bundle.*;
70
import org.netbeans.modules.hudson.spi.BuilderConnector;
71
import org.openide.windows.OutputListener;
72
import org.openide.xml.XMLUtil;
73
import org.w3c.dom.Element;
74
import org.w3c.dom.NodeList;
75
68
76
public class HudsonJobBuildImpl implements HudsonJobBuild, OpenableInBrowser {
69
public class HudsonJobBuildImpl implements HudsonJobBuild, OpenableInBrowser {
77
70
Lines 148-163 Link Here
148
        return HudsonJobBuildImpl_display_name(job.getDisplayName(), getNumber());
141
        return HudsonJobBuildImpl_display_name(job.getDisplayName(), getNumber());
149
    }
142
    }
150
143
151
    public static Color getColorForBuild(HudsonJobBuild build) {
144
    private ConsoleDataDisplayer createDisplayerFromImpl(
152
        switch (build.getResult()) {
145
            final ConsoleDataDisplayerImpl displayerImpl) {
153
            case SUCCESS:
146
        return new ConsoleDataDisplayer() {
154
                return Color.blue;
147
155
            case UNSTABLE:
148
            @Override
156
                return Color.yellow;
149
            public void open() {
157
            case FAILURE:
150
                displayerImpl.open();
158
                return Color.red;
151
            }
159
            default:
152
160
                return Color.grey;
153
            @Override
154
            public boolean writeLine(String line) {
155
                return displayerImpl.writeLine(line);
156
            }
157
158
            @Override
159
            public void close() {
160
                displayerImpl.close();
161
            }
162
        };
163
    }
164
165
    private FailureDataDisplayer createDisplayerFromImpl(
166
            final FailureDataDisplayerImpl displayerImpl) {
167
        return new FailureDataDisplayer() {
168
169
            @Override
170
            public void open() {
171
                displayerImpl.open();
172
            }
173
174
            @Override
175
            public void showSuite(FailureDataDisplayer.Suite suite) {
176
                displayerImpl.showSuite(suite);
177
            }
178
179
            @Override
180
            public void close() {
181
                displayerImpl.close();
182
            }
183
        };
184
    }
185
186
    @Override
187
    public boolean canShowConsole() {
188
        return connector.getConsoleDataProvider() != null;
189
    }
190
191
    @Override
192
    public void showConsole(ConsoleDataDisplayerImpl displayer) {
193
        BuilderConnector.ConsoleDataProvider cd = connector.getConsoleDataProvider();
194
        if (cd != null) {
195
            cd.showConsole(this, createDisplayerFromImpl(displayer));
196
        }
197
    }
198
199
    @Override
200
    public boolean canShowFailures() {
201
        return connector.getFailureDataProvider() != null;
202
    }
203
204
    @Override
205
    public void showFailures(FailureDataDisplayerImpl displayer) {
206
        BuilderConnector.FailureDataProvider fd = connector.getFailureDataProvider();
207
        if (fd != null) {
208
            fd.showFailures(this, createDisplayerFromImpl(displayer));
161
        }
209
        }
162
    }
210
    }
163
211
Lines 201-206 Link Here
201
            return HudsonJobBuildImpl_display_name(getDisplayName(), getNumber());
249
            return HudsonJobBuildImpl_display_name(getDisplayName(), getNumber());
202
        }
250
        }
203
251
252
        @Override
253
        public boolean canShowConsole() {
254
            return getBuild().canShowConsole();
255
        }
256
257
        @Override
258
        public void showConsole(ConsoleDataDisplayerImpl displayer) {
259
            BuilderConnector.ConsoleDataProvider cd = connector.getConsoleDataProvider();
260
            if (cd != null) {
261
                cd.showConsole(this, createDisplayerFromImpl(displayer));
262
            }
263
        }
264
265
        @Override
266
        public boolean canShowFailures() {
267
            return getBuild().canShowFailures();
268
        }
269
270
        @Override
271
        public void showFailures(FailureDataDisplayerImpl displayer) {
272
            BuilderConnector.FailureDataProvider fp = connector.getFailureDataProvider();
273
            if (fp != null) {
274
                fp.showFailures(this, createDisplayerFromImpl(displayer));
275
            }
276
        }
204
    }
277
    }
205
278
206
}
279
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonJobImpl.java (-56 / +1 lines)
Lines 55-69 Link Here
55
import org.netbeans.modules.hudson.api.HudsonJob;
55
import org.netbeans.modules.hudson.api.HudsonJob;
56
import org.netbeans.modules.hudson.api.HudsonJobBuild;
56
import org.netbeans.modules.hudson.api.HudsonJobBuild;
57
import org.netbeans.modules.hudson.api.HudsonView;
57
import org.netbeans.modules.hudson.api.HudsonView;
58
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
58
import static org.netbeans.modules.hudson.constants.HudsonJobConstants.*;
59
import static org.netbeans.modules.hudson.constants.HudsonJobConstants.*;
59
import static org.netbeans.modules.hudson.impl.Bundle.*;
60
import static org.netbeans.modules.hudson.impl.Bundle.*;
60
import org.netbeans.modules.hudson.spi.BuilderConnector;
61
import org.netbeans.modules.hudson.spi.BuilderConnector;
61
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
62
import org.netbeans.modules.hudson.util.HudsonPropertiesSupport;
62
import org.netbeans.modules.hudson.util.HudsonPropertiesSupport;
63
import org.openide.filesystems.FileSystem;
63
import org.openide.filesystems.FileSystem;
64
import org.openide.nodes.Node;
65
import org.openide.nodes.PropertySupport;
66
import org.openide.nodes.Sheet;
67
import org.openide.util.NbBundle.Messages;
64
import org.openide.util.NbBundle.Messages;
68
import org.openide.util.Utilities;
65
import org.openide.util.Utilities;
69
66
Lines 80-87 Link Here
80
    
77
    
81
    private HudsonInstanceImpl instance;
78
    private HudsonInstanceImpl instance;
82
    
79
    
83
    private Sheet.Set set;
84
85
    HudsonJobImpl(HudsonInstanceImpl instance) {
80
    HudsonJobImpl(HudsonInstanceImpl instance) {
86
        this.instance = instance;
81
        this.instance = instance;
87
    }
82
    }
Lines 162-208 Link Here
162
        instance.synchronize(false);
157
        instance.synchronize(false);
163
    }
158
    }
164
159
165
    @Messages({
166
        "TXT_Job_Prop_Name=Name",
167
        "DESC_Job_Prop_Name=Hudson's job name",
168
        "TXT_Job_Prop_Url=URL",
169
        "DESC_Job_Prop_Url=Hudson's job URL",
170
        "HudsonJobImpl.watched=Watched",
171
        "HudsonJobImpl.watched_desc=Whether you wish to be notified of failures in this job."
172
    })
173
    public Sheet.Set getSheetSet() {
174
        if (null == set) {
175
            set = Sheet.createPropertiesSet();
176
            
177
            // Set display name
178
            set.setDisplayName(getDisplayName());
179
            
180
            // Put properties in
181
            set.put(new Node.Property<?>[] {
182
                new HudsonJobProperty(JOB_NAME,
183
                        TXT_Job_Prop_Name(),
184
                        DESC_Job_Prop_Name()),
185
                new HudsonJobProperty(JOB_URL,
186
                        TXT_Job_Prop_Url(),
187
                        DESC_Job_Prop_Url()),
188
                new PropertySupport.ReadWrite<Boolean>("salient", Boolean.TYPE, // NOI18N
189
                        HudsonJobImpl_watched(),
190
                        HudsonJobImpl_watched_desc()) {
191
                    @Override public Boolean getValue() {
192
                        return isSalient();
193
                    }
194
                    @Override public void setValue(Boolean val) {
195
                        if (!getValue().equals(val)) {
196
                            setSalient(val);
197
                        }
198
                    }
199
                }
200
            });
201
        }
202
        
203
        return set;
204
    }
205
206
    @Override public FileSystem getRemoteWorkspace() {
160
    @Override public FileSystem getRemoteWorkspace() {
207
        return instance.getRemoteWorkspace(this);
161
        return instance.getRemoteWorkspace(this);
208
    }
162
    }
Lines 327-339 Link Here
327
            return url;
281
            return url;
328
        }
282
        }
329
    }
283
    }
330
331
    private class HudsonJobProperty extends PropertySupport.ReadOnly<String> {
332
        HudsonJobProperty(String key, String name, String desc) {
333
            super(key, String.class, name, desc);
334
        }
335
        public @Override String getValue() {
336
            return properties.getProperty(super.getName(), String.class);
337
        }
338
    }
339
}
284
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonManagerImpl.java (-82 / +16 lines)
Lines 44-68 Link Here
44
44
45
package org.netbeans.modules.hudson.impl;
45
package org.netbeans.modules.hudson.impl;
46
46
47
import java.beans.PropertyChangeEvent;
48
import java.beans.PropertyChangeListener;
49
import java.util.ArrayList;
47
import java.util.ArrayList;
50
import java.util.Arrays;
48
import java.util.Arrays;
51
import java.util.Collection;
49
import java.util.Collection;
52
import java.util.HashMap;
50
import java.util.HashMap;
53
import java.util.List;
51
import java.util.List;
54
import java.util.Map;
52
import java.util.Map;
55
import java.util.concurrent.ExecutionException;
56
import java.util.concurrent.Future;
57
import java.util.prefs.BackingStoreException;
53
import java.util.prefs.BackingStoreException;
58
import java.util.prefs.Preferences;
54
import java.util.prefs.Preferences;
59
import org.netbeans.api.project.Project;
60
import org.netbeans.api.project.ui.OpenProjects;
61
import org.netbeans.modules.hudson.api.HudsonChangeListener;
55
import org.netbeans.modules.hudson.api.HudsonChangeListener;
62
import org.netbeans.modules.hudson.api.HudsonInstance;
56
import org.netbeans.modules.hudson.api.HudsonInstance;
63
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
57
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
64
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
58
import org.netbeans.modules.hudson.spi.HudsonManagerAgent;
65
import org.openide.util.Exceptions;
59
import org.openide.util.Exceptions;
60
import org.openide.util.Lookup;
66
import org.openide.util.NbPreferences;
61
import org.openide.util.NbPreferences;
67
import org.openide.util.RequestProcessor;
62
import org.openide.util.RequestProcessor;
68
63
Lines 80-101 Link Here
80
    
75
    
81
    private Map<String, HudsonInstanceImpl> instances;
76
    private Map<String, HudsonInstanceImpl> instances;
82
    private final List<HudsonChangeListener> listeners = new ArrayList<HudsonChangeListener>();
77
    private final List<HudsonChangeListener> listeners = new ArrayList<HudsonChangeListener>();
83
    private PropertyChangeListener projectsListener;
78
    private final Collection<? extends HudsonManagerAgent> agents;
84
    private Map<Project, HudsonInstanceImpl> projectInstances = new HashMap<Project, HudsonInstanceImpl>();
85
    private final RequestProcessor.Task checkOpenProjects = RP.create(new Runnable() {
86
        public @Override void run() {
87
            checkOpenProjects();
88
        }
89
    });
90
    
79
    
91
    private HudsonManagerImpl() {
80
    private HudsonManagerImpl() {
92
        projectsListener = new PropertyChangeListener() {
81
        this.agents = Lookup.getDefault().lookupAll(HudsonManagerAgent.class);
93
            public void propertyChange(PropertyChangeEvent evt) {
94
                if (OpenProjects.PROPERTY_OPEN_PROJECTS.equals(evt.getPropertyName())) {
95
                    checkOpenProjects.schedule(0);
96
                }
97
            }
98
        };
99
    }
82
    }
100
    
83
    
101
    /**
84
    /**
Lines 116-122 Link Here
116
        
99
        
117
        if (null != getInstancesMap().put(instance.getUrl(), instance))
100
        if (null != getInstancesMap().put(instance.getUrl(), instance))
118
            return null;
101
            return null;
119
        
102
        for (HudsonManagerAgent agent: agents) {
103
            agent.instanceAdded(instance);
104
        }
120
        fireChangeListeners();
105
        fireChangeListeners();
121
        return instance;
106
        return instance;
122
    }
107
    }
Lines 131-136 Link Here
131
        // Stop autosynchronization if it's running
116
        // Stop autosynchronization if it's running
132
        instance.terminate();
117
        instance.terminate();
133
        
118
        
119
        for (HudsonManagerAgent agent : agents) {
120
            agent.instanceRemoved(instance);
121
        }
134
        // Fire changes into all listeners
122
        // Fire changes into all listeners
135
        fireChangeListeners();
123
        fireChangeListeners();
136
        
124
        
Lines 183-190 Link Here
183
    public void terminate() {
171
    public void terminate() {
184
        // Clear default instance
172
        // Clear default instance
185
        defaultInstance = null;
173
        defaultInstance = null;
186
        OpenProjects.getDefault().removePropertyChangeListener(projectsListener);
174
        for (HudsonManagerAgent agent: agents) {
187
        projectInstances.clear();
175
            agent.terminate();
176
        }
188
        // Terminate instances
177
        // Terminate instances
189
        for (HudsonInstance instance : getInstances())
178
        for (HudsonInstance instance : getInstances())
190
            ((HudsonInstanceImpl) instance).terminate();
179
            ((HudsonInstanceImpl) instance).terminate();
Lines 221-226 Link Here
221
210
222
    private void init() {
211
    private void init() {
223
        RP.post(new Runnable() {
212
        RP.post(new Runnable() {
213
            @Override
224
            public void run() {
214
            public void run() {
225
                try {
215
                try {
226
                    try {
216
                    try {
Lines 242-310 Link Here
242
                        Exceptions.printStackTrace(ex);
232
                        Exceptions.printStackTrace(ex);
243
                    }
233
                    }
244
                } finally {
234
                } finally {
245
                    checkOpenProjects();
246
                    OpenProjects.getDefault().addPropertyChangeListener(projectsListener);
247
                    // Fire changes
235
                    // Fire changes
248
                    fireChangeListeners();
236
                    fireChangeListeners();
249
                }
237
                }
250
            }
238
            }
251
        });
239
        });
252
    }
240
        for (HudsonManagerAgent agent: agents) {
253
241
            agent.start();
254
255
    private void checkOpenProjects() {
256
        try {
257
            Future<Project[]> fut = OpenProjects.getDefault().openProjects();
258
            Project[] prjs = fut.get();
259
            for (Project project : prjs) {
260
                boolean exists = false;
261
                if (projectInstances.containsKey(project)) {
262
                    exists = true;
263
                }
264
                ProjectHudsonProvider.Association assoc = ProjectHudsonProvider.getDefault().findAssociation(project);
265
                if (assoc != null && !exists) {
266
                    String url = assoc.getServerUrl();
267
                    HudsonInstanceImpl in = getInstance(url);
268
                    if (in != null && in.getProperties() instanceof ProjectHIP) {
269
                        ProjectHIP props = (ProjectHIP) in.getProperties();
270
                        props.addProvider(project);
271
                        projectInstances.put(project,in);
272
                    } else if (in == null) {
273
                        ProjectHIP props = new ProjectHIP();
274
                        props.addProvider(project);
275
                        addInstance(HudsonInstanceImpl.createHudsonInstance(props, false));
276
                        HudsonInstanceImpl impl = getInstance(props.get(INSTANCE_URL));
277
                        projectInstances.put(project, impl);
278
                    }
279
                } else if (assoc == null && exists) {
280
                    HudsonInstanceImpl remove = projectInstances.remove(project);
281
                    if (remove != null && remove.getProperties() instanceof ProjectHIP) {
282
                        ProjectHIP props = (ProjectHIP)remove.getProperties();
283
                        props.removeProvider(project);
284
                        if (props.getProviders().isEmpty()) {
285
                            removeInstance(remove);
286
                        }
287
                    }
288
                }
289
            }
290
            ArrayList<Project> newprjs = new ArrayList<Project>(projectInstances.keySet());
291
            newprjs.removeAll(Arrays.asList(prjs));
292
            for (Project project : newprjs) {
293
                HudsonInstanceImpl remove = projectInstances.remove(project);
294
                if (remove != null && remove.getProperties() instanceof ProjectHIP
295
                        && !remove.isPersisted()) {
296
                    ProjectHIP props = (ProjectHIP)remove.getProperties();
297
                    props.removeProvider(project);
298
                    if (props.getProviders().isEmpty()) {
299
                        removeInstance(remove);
300
                    }
301
                }
302
            }
303
        } catch (InterruptedException ex) {
304
            Exceptions.printStackTrace(ex);
305
        } catch (ExecutionException ex) {
306
            Exceptions.printStackTrace(ex);
307
        }
242
        }
308
    }
243
    }
309
310
}
244
}
(-)a/hudson/src/org/netbeans/modules/hudson/impl/HudsonViewImpl.java (-1 / +1 lines)
Lines 46-52 Link Here
46
46
47
import org.netbeans.modules.hudson.api.HudsonInstance;
47
import org.netbeans.modules.hudson.api.HudsonInstance;
48
import org.netbeans.modules.hudson.api.HudsonView;
48
import org.netbeans.modules.hudson.api.HudsonView;
49
import org.netbeans.modules.hudson.ui.interfaces.OpenableInBrowser;
49
import org.netbeans.modules.hudson.api.ui.OpenableInBrowser;
50
import static org.netbeans.modules.hudson.constants.HudsonViewConstants.*;
50
import static org.netbeans.modules.hudson.constants.HudsonViewConstants.*;
51
import org.netbeans.modules.hudson.util.HudsonPropertiesSupport;
51
import org.netbeans.modules.hudson.util.HudsonPropertiesSupport;
52
52
(-)a/hudson/src/org/netbeans/modules/hudson/impl/ProjectHIP.java (-108 lines)
Lines 1-108 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 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
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
45
package org.netbeans.modules.hudson.impl;
46
47
import java.util.ArrayList;
48
import java.util.HashSet;
49
import java.util.List;
50
import java.util.Set;
51
import org.netbeans.api.project.Project;
52
import static org.netbeans.modules.hudson.constants.HudsonInstanceConstants.*;
53
import org.netbeans.modules.hudson.spi.ProjectHudsonProvider;
54
55
/**
56
 *
57
 * @author mkleint
58
 */
59
class ProjectHIP extends HudsonInstanceProperties {
60
61
    private final Set<Project> providers = new HashSet<Project>();
62
    public ProjectHIP() {
63
        super("", "", "60"); // NOI18N
64
        put(INSTANCE_PERSISTED, FALSE);
65
    }
66
67
    public void addProvider(Project prov) {
68
        synchronized (providers) {
69
            providers.add(prov);
70
        }
71
        ProjectHudsonProvider.Association assoc = ProjectHudsonProvider.getDefault().findAssociation(prov);
72
        if (assoc != null) {
73
            String u = assoc.getServerUrl();
74
            put(INSTANCE_URL, u);
75
            put(INSTANCE_NAME, HudsonManagerImpl.simplifyServerLocation(u, false));
76
            setPreferredJobs();
77
        }
78
        //TODO listen on changes from the provider and refire them as changed properties.
79
    }
80
81
    public void removeProvider(Project prov) {
82
        synchronized (providers) {
83
            providers.remove(prov);
84
        }
85
        setPreferredJobs();
86
    }
87
88
    public Set<Project> getProviders() {
89
        synchronized (providers) {
90
            return new HashSet<Project>(providers);
91
        }
92
    }
93
94
    private void setPreferredJobs() {
95
        List<String> names = new ArrayList<String>();
96
        for (Project prj : getProviders()) {
97
            ProjectHudsonProvider.Association assoc = ProjectHudsonProvider.getDefault().findAssociation(prj);
98
            if (assoc != null) {
99
                String name = assoc.getJobName();
100
                if (name != null) {
101
                    names.add(name);
102
                }
103
            }
104
        }
105
        put(INSTANCE_PREF_JOBS, join(names));
106
    }
107
108
}
(-)a/hudson/src/org/netbeans/modules/hudson/spi/BuilderConnector.java (-15 / +30 lines)
Lines 56-61 Link Here
56
import org.netbeans.modules.hudson.api.HudsonJobBuild.Result;
56
import org.netbeans.modules.hudson.api.HudsonJobBuild.Result;
57
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
57
import org.netbeans.modules.hudson.api.HudsonMavenModuleBuild;
58
import org.netbeans.modules.hudson.api.HudsonVersion;
58
import org.netbeans.modules.hudson.api.HudsonVersion;
59
import org.netbeans.modules.hudson.api.ui.ConsoleDataDisplayer;
60
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer;
59
61
60
/**
62
/**
61
 * Interface of Hudson connectors. It specifies how data should be accessed and
63
 * Interface of Hudson connectors. It specifies how data should be accessed and
Lines 155-174 Link Here
155
    public abstract void startJob(@NonNull HudsonJob job);
157
    public abstract void startJob(@NonNull HudsonJob job);
156
158
157
    /**
159
    /**
158
     * Get displayer for build console output.
160
     * Get provider of data for build console output.
159
     *
161
     *
160
     * @return Console displayer, or null if it is not available for this
162
     * @return Console data provider, or null if it is not available for this
161
     * builder.
163
     * builder.
162
     */
164
     */
163
    public abstract @CheckForNull ConsoleDisplayer getConsoleDisplayer();
165
    public abstract @CheckForNull ConsoleDataProvider getConsoleDataProvider();
164
166
165
    /**
167
    /**
166
     * Get displayer for failed tests of builds.
168
     * Get provider of data for failure displayer.
167
     *
169
     *
168
     * @return Failure displayer, or null if it is not available for this
170
     * @return Failure data provider, or null if it is not available for this
169
     * builder.
171
     * builder.
170
     */
172
     */
171
    public abstract @CheckForNull FailureDisplayer getFailureDisplayer();
173
    public abstract @CheckForNull FailureDataProvider getFailureDataProvider();
172
174
173
    /**
175
    /**
174
     * Get a collection of changes that have triggered the build.
176
     * Get a collection of changes that have triggered the build.
Lines 176-214 Link Here
176
    public abstract Collection<? extends HudsonJobChangeItem> getJobBuildChanges(HudsonJobBuild build);
178
    public abstract Collection<? extends HudsonJobChangeItem> getJobBuildChanges(HudsonJobBuild build);
177
179
178
    /**
180
    /**
179
     * A displayer that can show console output of builds to the user. They can
181
     * A provider of console output of builds. They can
180
     * be shown in output window, external browser, etc.
182
     * be shown in output window, external browser, etc.
181
     */
183
     */
182
    public static abstract class ConsoleDisplayer {
184
    public static abstract class ConsoleDataProvider {
183
185
184
        /**
186
        /**
185
         * Show build console of a hudson job build.
187
         * Show build console of a hudson job build using a displayer.
188
         *
189
         * @param build Hudson job build.
190
         * @param displayer Displayer to which the data will be passed.
186
         */
191
         */
187
        public abstract void showConsole(@NonNull HudsonJobBuild build);
192
        public abstract void showConsole(@NonNull HudsonJobBuild build, ConsoleDataDisplayer displayer);
188
193
189
        /**
194
        /**
190
         * Show build console of a hudson maven module build.
195
         * Show build console of a hudson maven module build.
196
         *
197
         * @param modBuild Hudson Maven module build.
198
         * @param displayer Displayer to which the data will be passed.
191
         */
199
         */
192
        public abstract void showConsole(
200
        public abstract void showConsole(
193
                @NonNull HudsonMavenModuleBuild modBuild);
201
                @NonNull HudsonMavenModuleBuild modBuild, ConsoleDataDisplayer displayer);
194
    }
202
    }
195
203
196
    /**
204
    /**
197
     * A displayer that can visualize failures of builds. They can be displayer
205
     * A provider of info about test failures. They can be displayer
198
     * in test results window, output window, external browser, etc.
206
     * in test results window, output window, external browser, etc.
199
     */
207
     */
200
    public static abstract class FailureDisplayer {
208
    public static abstract class FailureDataProvider {
201
209
202
        /**
210
        /**
203
         * Show failures of a hudson job build.
211
         * Show failures of a hudson job build.
212
         * @param build Hudson job build.
213
         * @param displayer Displayer to which the data will be passed.
204
         */
214
         */
205
        public abstract void showFailures(@NonNull HudsonJobBuild build);
215
        public abstract void showFailures(@NonNull HudsonJobBuild build,
216
                @NonNull FailureDataDisplayer displayer);
206
217
207
        /**
218
        /**
208
         * Show failures of a hudson maven module build.
219
         * Show failures of a hudson maven module build.
220
         *
221
         * @param moduleBuild Hudson maven module build.
222
         * @param displayer Displayer to which the data will be passed.
209
         */
223
         */
210
        public abstract void showFailures(
224
        public abstract void showFailures(
211
                @NonNull HudsonMavenModuleBuild moduleBuild);
225
                @NonNull HudsonMavenModuleBuild moduleBuild,
226
                @NonNull FailureDataDisplayer displayer);
212
    }
227
    }
213
228
214
    /**
229
    /**
(-)a/hudson/src/org/netbeans/modules/hudson/spi/ConsoleDataDisplayerImpl.java (+68 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.hudson.spi;
43
44
/**
45
 * Displays data from {@link BuilderConnector.ConsoleDataProvider}.
46
 *
47
 * @author jhavlin
48
 */
49
public abstract class ConsoleDataDisplayerImpl {
50
51
    /**
52
     * Prepare the displayer for writing.
53
     */
54
    public abstract void open();
55
56
    /**
57
     * Write one line of line to the displayer.
58
     *
59
     * @param line One line of console output.
60
     * @return True if writing was successful, false otherwise.
61
     */
62
    public abstract boolean writeLine(String line);
63
64
    /**
65
     * Finish writing to the displayer.
66
     */
67
    public abstract void close();
68
}
(-)a/hudson/src/org/netbeans/modules/hudson/spi/FailureDataDisplayerImpl.java (+69 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.hudson.spi;
43
44
import org.netbeans.modules.hudson.api.ui.FailureDataDisplayer.Suite;
45
46
/**
47
 * Displays data from {@link BuilderConnector.FailureDataProvider}.
48
 *
49
 * @author jhavlin
50
 */
51
public abstract class FailureDataDisplayerImpl {
52
53
    /**
54
     * Prepare the displayer.
55
     */
56
    public abstract void open();
57
58
    /**
59
     * Display result of a test suite.
60
     *
61
     * @param suite Test suite data.
62
     */
63
    public abstract void showSuite(Suite suite);
64
65
    /**
66
     * Finish writing to the displayer.
67
     */
68
    public abstract void close();
69
}
(-)a/hudson/src/org/netbeans/modules/hudson/spi/HudsonLogger.java (-84 lines)
Lines 42-58 Link Here
42
42
43
package org.netbeans.modules.hudson.spi;
43
package org.netbeans.modules.hudson.spi;
44
44
45
import java.awt.EventQueue;
46
import java.io.IOException;
47
import java.util.logging.Level;
48
import java.util.logging.Logger;
49
import org.netbeans.modules.hudson.api.HudsonJob;
45
import org.netbeans.modules.hudson.api.HudsonJob;
50
import org.openide.cookies.EditorCookie;
51
import org.openide.cookies.LineCookie;
52
import org.openide.cookies.OpenCookie;
53
import org.openide.filesystems.FileObject;
54
import org.openide.loaders.DataObject;
55
import org.openide.text.Line;
56
import org.openide.windows.OutputWriter;
46
import org.openide.windows.OutputWriter;
57
47
58
/**
48
/**
Lines 79-157 Link Here
79
         * @return true if this logger handled the output, false otherwise
69
         * @return true if this logger handled the output, false otherwise
80
         */
70
         */
81
        boolean handle(String line, OutputWriter stream);
71
        boolean handle(String line, OutputWriter stream);
82
83
    }
72
    }
84
85
    /**
86
     * Utilities for use by a logger.
87
     */
88
    class Helper {
89
90
        private static final Logger LOG = Logger.getLogger(HudsonLogger.class.getName());
91
92
        /**
93
         * Try to open a file, possibly at a given position.
94
         * @param f a file to open
95
         * @param row the row number (zero-based), or -1 for none
96
         * @param col the column number (zero-based), or -1 for none
97
         * @param force true to forcibly open the file, false to just scroll if already open
98
         */
99
        public static void openAt(FileObject f, int row, final int col, final boolean force) {
100
            try {
101
                DataObject d = DataObject.find(f);
102
                if (row == -1) {
103
                    if (force) {
104
                        Runnable r;
105
                        final EditorCookie c = d.getLookup().lookup(EditorCookie.class);
106
                        if (c != null) {
107
                            r = new Runnable() {
108
                                public void run() {
109
                                    try {
110
                                        c.openDocument();
111
                                    } catch (IOException x) {
112
                                        LOG.log(Level.INFO, null, x);
113
                                    }
114
                                }
115
                            };
116
                        } else {
117
                            LOG.fine("no EditorCookie found for " + f);
118
                            final OpenCookie o = d.getLookup().lookup(OpenCookie.class);
119
                            if (o == null) {
120
                                LOG.fine("no OpenCookie found for " + f);
121
                                return;
122
                            }
123
                            r = new Runnable() {
124
                                public void run() {
125
                                    o.open();
126
                                }
127
                            };
128
                        }
129
                        EventQueue.invokeLater(r);
130
                    }
131
                    return;
132
                }
133
                LineCookie c = d.getLookup().lookup(LineCookie.class);
134
                if (c == null) {
135
                    LOG.fine("no LineCookie found for " + f);
136
                    openAt(f, -1, -1, force);
137
                    return;
138
                }
139
                try {
140
                    final Line l = c.getLineSet().getOriginal(row);
141
                    EventQueue.invokeLater(new Runnable() {
142
                        public void run() {
143
                            l.show(force ? Line.ShowOpenType.REUSE : Line.ShowOpenType.NONE,
144
                                    force ? Line.ShowVisibilityType.FOCUS : Line.ShowVisibilityType.FRONT, col);
145
                        }
146
                    });
147
                } catch (IndexOutOfBoundsException x) {
148
                    LOG.log(Level.INFO, null, x);
149
                }
150
            } catch (IOException x) {
151
                LOG.log(Level.INFO, null, x);
152
            }
153
        }
154
155
    }
156
157
}
73
}
(-)a/hudson/src/org/netbeans/modules/hudson/spi/HudsonManagerAgent.java (+82 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.hudson.spi;
43
44
import org.netbeans.modules.hudson.api.HudsonInstance;
45
46
/**
47
 * Agent that is informed about addition and removal of Hudson instances, and
48
 * that helps the HudsonManager automatically add and remove Hudson instances,
49
 * depending on the state of the rest of the IDE. For example, some projects can
50
 * have associated Hudson builder. When such project is opened, its Hudson
51
 * instance should be added to the manager.
52
 *
53
 * @author jhavlin
54
 */
55
public abstract class HudsonManagerAgent {
56
57
    /**
58
     * Called when an instance is added to the manager (including the ones added
59
     * by the manager agent, too).
60
     *
61
     * @param instance Hudson instanca that has been just added.
62
     */
63
    public abstract void instanceAdded(HudsonInstance instance);
64
65
    /**
66
     * Called when an instance is removed from the manager (including the ones
67
     * removed by the manager agent, too).
68
     *
69
     * @param instance Hudson instance that has been just removed.
70
     */
71
    public abstract void instanceRemoved(HudsonInstance instance);
72
73
    /**
74
     * Start the agent. Allocate all resources, e.g. listeners.
75
     */
76
    public abstract void start();
77
78
    /**
79
     * Terminate the agent. Release all resources allocated in {@link #start()}.
80
     */
81
    public abstract void terminate();
82
}
(-)a/hudson/src/org/netbeans/modules/hudson/spi/HudsonSCM.java (-91 / +77 lines)
Lines 42-67 Link Here
42
42
43
package org.netbeans.modules.hudson.spi;
43
package org.netbeans.modules.hudson.spi;
44
44
45
import java.awt.BorderLayout;
46
import java.awt.EventQueue;
47
import java.io.File;
45
import java.io.File;
48
import java.io.IOException;
49
import java.util.List;
46
import java.util.List;
50
import java.util.logging.Level;
47
import javax.swing.JButton;
51
import java.util.logging.Logger;
52
import org.netbeans.api.diff.Diff;
53
import org.netbeans.api.diff.DiffView;
54
import org.netbeans.api.diff.StreamSource;
55
import org.netbeans.modules.hudson.api.HudsonJob;
48
import org.netbeans.modules.hudson.api.HudsonJob;
56
import org.netbeans.modules.hudson.api.HudsonJobBuild;
49
import org.netbeans.modules.hudson.api.HudsonJobBuild;
57
import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus;
58
import org.netbeans.modules.hudson.api.Utilities;
59
import org.openide.awt.StatusDisplayer;
60
import org.openide.util.NbBundle.Messages;
61
import static org.netbeans.modules.hudson.spi.Bundle.*;
62
import org.openide.windows.TopComponent;
63
import org.w3c.dom.Document;
50
import org.w3c.dom.Document;
64
import org.w3c.dom.Element;
65
51
66
/**
52
/**
67
 * Represents one kind of SCM (version control) supported by the Hudson integration.
53
 * Represents one kind of SCM (version control) supported by the Hudson integration.
Lines 99-104 Link Here
99
    }
85
    }
100
86
101
    /**
87
    /**
88
     * A problem with the SCM configuration.
89
     */
90
    public static final class ConfigurationStatus {
91
92
        private String errorMessage;
93
        private String warningMessage;
94
        private JButton extraButton;
95
96
        private ConfigurationStatus() {
97
        }
98
99
        /**
100
         * Creates a valid configuration.
101
         */
102
        public static ConfigurationStatus valid() {
103
            return new ConfigurationStatus();
104
        }
105
106
        /**
107
         * Creates a configuration with a fatal error.
108
         */
109
        public static ConfigurationStatus withError(String error) {
110
            ConfigurationStatus s = new ConfigurationStatus();
111
            s.errorMessage = error;
112
            return s;
113
        }
114
115
        /**
116
         * Creates a configuration with a nonfatal warning.
117
         */
118
        public static ConfigurationStatus withWarning(String warning) {
119
            ConfigurationStatus s = new ConfigurationStatus();
120
            s.warningMessage = warning;
121
            return s;
122
        }
123
124
        /**
125
         * Creates a similar configuration but with an extra button added to the
126
         * dialog.
127
         *
128
         * @see NotifyDescriptor#setAdditionalOptions
129
         */
130
        public ConfigurationStatus withExtraButton(JButton extraButton) {
131
            if (this.extraButton != null) {
132
                throw new IllegalArgumentException();
133
            }
134
            ConfigurationStatus s = new ConfigurationStatus();
135
            s.errorMessage = errorMessage;
136
            s.warningMessage = warningMessage;
137
            s.extraButton = extraButton;
138
            return s;
139
        }
140
141
        /**
142
         * for internal use only
143
         */
144
        public String getErrorMessage() {
145
            return errorMessage;
146
        }
147
148
        /**
149
         * for internal use only
150
         */
151
        public String getWarningMessage() {
152
            return warningMessage;
153
        }
154
155
        /**
156
         * for internal use only
157
         */
158
        public JButton getExtraButton() {
159
            return extraButton;
160
        }
161
    }
162
163
    /**
102
     * Attempts to convert a path in a remote Hudson workspace to a local file path.
164
     * Attempts to convert a path in a remote Hudson workspace to a local file path.
103
     * May use SCM information to guess at how these paths should be aligned.
165
     * May use SCM information to guess at how these paths should be aligned.
104
     * @param job a Hudson job
166
     * @param job a Hudson job
Lines 118-197 Link Here
118
     * @return a list of parsed changelog items, or null if the SCM is unrecognized
180
     * @return a list of parsed changelog items, or null if the SCM is unrecognized
119
     */
181
     */
120
    List<? extends HudsonJobChangeItem> parseChangeSet(HudsonJobBuild build);
182
    List<? extends HudsonJobChangeItem> parseChangeSet(HudsonJobBuild build);
121
122
    /**
123
     * Convenience methods for SCM implementations.
124
     */
125
    class Helper {
126
127
        private static final Logger LOG = Logger.getLogger(HudsonSCM.class.getName());
128
129
        private Helper() {}
130
131
        /**
132
         * Add an SCM polling trigger.
133
         * @param configXml a {@code config.xml}
134
         */
135
        public static void addTrigger(Document configXml) {
136
            Element root = configXml.getDocumentElement();
137
            root.appendChild(configXml.createElement("triggers")). // NOI18N // XXX reuse existing <triggers> if found
138
                    appendChild(configXml.createElement("hudson.triggers.SCMTrigger")). // NOI18N
139
                    appendChild(configXml.createElement("spec")). // NOI18N
140
                    // XXX pretty arbitrary but seems like a decent first guess
141
                    appendChild(configXml.createTextNode("@hourly")); // NOI18N
142
        }
143
144
        @Deprecated
145
        public static String xpath(String expr, Element xml) {
146
            return Utilities.xpath(expr, xml);
147
        }
148
149
        /**
150
         * Just notify the user that a diff will be shown for a given path.
151
         * @param path a path, probably somehow repo-relative
152
         */
153
        @Messages({"# {0} - portion of file path", "HudsonSCM.loading_diff=Loading diff for {0}..."})
154
        public static void noteWillShowDiff(String path) {
155
            StatusDisplayer.getDefault().setStatusText(HudsonSCM_loading_diff(path));
156
        }
157
158
        /**
159
         * Display a diff window for a file.
160
         * @param before the former contents
161
         * @param after the new contents
162
         * @param path some representation of the file path
163
         */
164
        @Messages({"# {0} - file basename", "HudsonSCM.diffing=Diffing {0}"})
165
        public static void showDiff(final StreamSource before, final StreamSource after, final String path) {
166
            EventQueue.invokeLater(new Runnable() {
167
                @Override public void run() {
168
                    try {
169
                        DiffView view = Diff.getDefault().createDiff(before, after);
170
                        // XXX reuse the same TC
171
                        DiffTopComponent tc = new DiffTopComponent(view);
172
                        tc.setName(path);
173
                        tc.setDisplayName(HudsonSCM_diffing(path.replaceFirst(".+/", "")));
174
                        tc.open();
175
                        tc.requestActive();
176
                    } catch (IOException x) {
177
                        LOG.log(Level.INFO, null, x);
178
                    }
179
                }
180
            });
181
        }
182
        private static class DiffTopComponent extends TopComponent {
183
            DiffTopComponent(DiffView view) {
184
                setLayout(new BorderLayout());
185
                add(view.getComponent(), BorderLayout.CENTER);
186
            }
187
            public @Override int getPersistenceType() {
188
                return TopComponent.PERSISTENCE_NEVER;
189
            }
190
            protected @Override String preferredID() {
191
                return "DiffTopComponent"; // NOI18N
192
            }
193
        }
194
195
    }
196
197
}
183
}
(-)a/nbbuild/cluster.properties (+1 lines)
Lines 319-324 Link Here
319
        hudson.mercurial,\
319
        hudson.mercurial,\
320
        hudson.subversion,\
320
        hudson.subversion,\
321
        hudson.tasklist,\
321
        hudson.tasklist,\
322
	hudson.ui,\
322
        ide.kit,\
323
        ide.kit,\
323
        image,\
324
        image,\
324
        javascript2.editor,\
325
        javascript2.editor,\
(-)a/odcs.hudson/nbproject/project.xml (-1 / +9 lines)
Lines 43-49 Link Here
43
                    <build-prerequisite/>
43
                    <build-prerequisite/>
44
                    <compile-dependency/>
44
                    <compile-dependency/>
45
                    <run-dependency>
45
                    <run-dependency>
46
                        <specification-version>1.27</specification-version>
46
                        <specification-version>2.0</specification-version>
47
                    </run-dependency>
48
                </dependency>
49
                <dependency>
50
                    <code-name-base>org.netbeans.modules.hudson.ui</code-name-base>
51
                    <build-prerequisite/>
52
                    <compile-dependency/>
53
                    <run-dependency>
54
                        <specification-version>1.0</specification-version>
47
                    </run-dependency>
55
                    </run-dependency>
48
                </dependency>
56
                </dependency>
49
                <dependency>
57
                <dependency>
(-)a/odcs.hudson/src/org/netbeans/modules/odcs/hudson/ODCSBuilderAccessor.java (-2 / +2 lines)
Lines 72-80 Link Here
72
import org.netbeans.modules.hudson.api.HudsonJob;
72
import org.netbeans.modules.hudson.api.HudsonJob;
73
import org.netbeans.modules.hudson.api.HudsonJobBuild;
73
import org.netbeans.modules.hudson.api.HudsonJobBuild;
74
import org.netbeans.modules.hudson.api.HudsonManager;
74
import org.netbeans.modules.hudson.api.HudsonManager;
75
import org.netbeans.modules.hudson.api.UI;
75
import org.netbeans.modules.hudson.ui.api.UI;
76
import org.netbeans.modules.odcs.api.ODCSProject;
76
import org.netbeans.modules.odcs.api.ODCSServer;
77
import org.netbeans.modules.odcs.api.ODCSServer;
77
import org.netbeans.modules.odcs.api.ODCSProject;
78
import org.netbeans.modules.odcs.ui.api.ODCSUiServer;
78
import org.netbeans.modules.odcs.ui.api.ODCSUiServer;
79
import org.netbeans.modules.team.ui.common.DefaultDashboard;
79
import org.netbeans.modules.team.ui.common.DefaultDashboard;
80
import org.netbeans.modules.team.ui.spi.BuildHandle;
80
import org.netbeans.modules.team.ui.spi.BuildHandle;
(-)a/odcs.hudson/test/unit/src/org/netbeans/modules/odcs/hudson/ODCSBuilderAccessorTest.java (-27 / +7 lines)
Lines 151-176 Link Here
151
    }
151
    }
152
152
153
    /**
153
    /**
154
     * Check that mock instances work as expected.
155
     */
156
    @Test
157
    public void testMocks() throws ODCSException, MalformedURLException,
158
            MalformedURLException {
159
160
        ODCSClient client = ODCSFactory.getInstance().createClient(
161
                "http://test/", new PasswordAuthentication(
162
                "mockUser", "password".toCharArray()));
163
        assertNotNull(client);
164
        Project project = client.getProjectById("mockProject");
165
        assertEquals("Mock Test Project", project.getDescription());
166
167
        ProjectHandle<ODCSProject> handle = TestUtils.createMockHandle(
168
                "http://test/", "mockProject");
169
        assertNotNull(handle);
170
        assertEquals("Mock Project", handle.getDisplayName());
171
    }
172
173
    /**
174
     * Check that the job handle for mock job has correct name.
154
     * Check that the job handle for mock job has correct name.
175
     */
155
     */
176
    @Test
156
    @Test
Lines 430-448 Link Here
430
        }
410
        }
431
411
432
        @Override
412
        @Override
433
        public ConsoleDisplayer getConsoleDisplayer() {
413
        public Collection<? extends HudsonJobChangeItem> getJobBuildChanges(HudsonJobBuild build) {
414
            return Collections.emptyList();
415
        }
416
417
        @Override
418
        public ConsoleDataProvider getConsoleDataProvider() {
434
            return null;
419
            return null;
435
        }
420
        }
436
421
437
        @Override
422
        @Override
438
        public FailureDisplayer getFailureDisplayer() {
423
        public FailureDataProvider getFailureDataProvider() {
439
            return null;
424
            return null;
440
        }
425
        }
441
442
        @Override
443
        public Collection<? extends HudsonJobChangeItem> getJobBuildChanges(HudsonJobBuild build) {
444
            return Collections.emptyList();
445
        }
446
    }
426
    }
447
427
448
    /**
428
    /**

Return to bug 229459