Skip to content

Commit a7be71c

Browse files
BananeweizenCalixte
authored andcommitted
Use OSGi service for UI startup handler
Bundle activators should do as little work as possible. Therefore move the registration of the window listener out of the bundle activation and instead have OSGi call back when the application has started. That's later, that improves startup performance and that should avoid race conditions on the workbench access.
1 parent 694ca5c commit a7be71c

File tree

6 files changed

+157
-94
lines changed

6 files changed

+157
-94
lines changed

net.sf.eclipsecs.ui/.project

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525
<arguments>
2626
</arguments>
2727
</buildCommand>
28+
<buildCommand>
29+
<name>org.eclipse.pde.ds.core.builder</name>
30+
<arguments>
31+
</arguments>
32+
</buildCommand>
2833
</buildSpec>
2934
<natures>
3035
<nature>org.eclipse.m2e.core.maven2Nature</nature>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
dsVersion=V1_3
2+
eclipse.preferences.version=1
3+
enabled=true
4+
generateBundleActivationPolicyLazy=true
5+
path=OSGI-INF
6+
validationErrorLevel=error
7+
validationErrorLevel.missingImplicitUnbindMethod=error

net.sf.eclipsecs.ui/META-INF/MANIFEST.MF

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ Require-Bundle: net.sf.eclipsecs.core,
1010
org.eclipse.core.expressions,
1111
org.eclipse.ui.workbench,
1212
org.eclipse.jface,
13-
org.eclipse.help;bundle-version="3.9.0"
13+
org.eclipse.help;bundle-version="3.9.0",
14+
org.eclipse.e4.ui.workbench;bundle-version="1.13.200"
15+
Service-Component: OSGI-INF/net.sf.eclipsecs.ui.ApplicationStartedHandler.xml
1416
Bundle-RequiredExecutionEnvironment: JavaSE-17
1517
Export-Package: net.sf.eclipsecs.ui,
1618
net.sf.eclipsecs.ui.properties.filter,
@@ -66,6 +68,7 @@ Import-Package: org.apache.commons.lang3;version="3.12.0",
6668
org.eclipse.ui.texteditor,
6769
org.eclipse.ui.views.markers,
6870
org.osgi.framework,
71+
org.osgi.service.event;version="[1.4.0,2.0.0)",
6972
org.osgi.service.prefs
7073
Automatic-Module-Name: net.sf.eclipsecs.ui
7174

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="net.sf.eclipsecs.ui.ApplicationStartedHandler">
3+
<property name="event.topics" value="org/eclipse/e4/ui/LifeCycle/appStartupComplete"/>
4+
<service>
5+
<provide interface="org.osgi.service.event.EventHandler"/>
6+
</service>
7+
<implementation class="net.sf.eclipsecs.ui.ApplicationStartedHandler"/>
8+
</scr:component>
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//============================================================================
2+
//
3+
// Copyright (C) 2003-2023 the original author or authors.
4+
//
5+
// This library is free software; you can redistribute it and/or
6+
// modify it under the terms of the GNU Lesser General Public
7+
// License as published by the Free Software Foundation; either
8+
// version 2.1 of the License, or (at your option) any later version.
9+
//
10+
// This library is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
// Lesser General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Lesser General Public
16+
// License along with this library; if not, write to the Free Software
17+
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18+
//
19+
//============================================================================
20+
21+
package net.sf.eclipsecs.ui;
22+
23+
import org.osgi.service.component.annotations.Component;
24+
import org.osgi.service.event.EventConstants;
25+
import org.osgi.service.event.EventHandler;
26+
27+
import net.sf.eclipsecs.core.jobs.AbstractCheckJob;
28+
import net.sf.eclipsecs.ui.properties.filter.CheckFileOnOpenPartListener;
29+
30+
import java.util.Collection;
31+
import java.util.Collections;
32+
import java.util.HashSet;
33+
34+
import org.eclipse.e4.ui.workbench.UIEvents;
35+
import org.eclipse.ui.IEditorReference;
36+
import org.eclipse.ui.IWindowListener;
37+
import org.eclipse.ui.IWorkbench;
38+
import org.eclipse.ui.IWorkbenchPage;
39+
import org.eclipse.ui.IWorkbenchPartReference;
40+
import org.eclipse.ui.IWorkbenchWindow;
41+
import org.eclipse.ui.PlatformUI;
42+
import org.eclipse.ui.progress.IProgressService;
43+
44+
/**
45+
* Event handler being called when the eclipse application has started.
46+
*/
47+
@Component(property = EventConstants.EVENT_TOPIC + "=" + UIEvents.UILifeCycle.APP_STARTUP_COMPLETE)
48+
public class ApplicationStartedHandler implements EventHandler {
49+
50+
private final CheckFileOnOpenPartListener mPartListener = new CheckFileOnOpenPartListener();
51+
52+
private final IWindowListener mWindowListener = new IWindowListener() {
53+
54+
@Override
55+
public void windowOpened(IWorkbenchWindow window) {
56+
window.getPartService().addPartListener(mPartListener);
57+
}
58+
59+
@Override
60+
public void windowActivated(IWorkbenchWindow window) {
61+
}
62+
63+
@Override
64+
public void windowClosed(IWorkbenchWindow window) {
65+
window.getPartService().removePartListener(mPartListener);
66+
67+
}
68+
69+
@Override
70+
public void windowDeactivated(IWorkbenchWindow window) {
71+
}
72+
73+
};
74+
75+
@Override
76+
public void handleEvent(org.osgi.service.event.Event event) {
77+
if (!UIEvents.UILifeCycle.APP_STARTUP_COMPLETE.equals(event.getTopic())) {
78+
return;
79+
}
80+
registerListener();
81+
registerProgressIcon();
82+
}
83+
84+
private void registerListener() {
85+
// add listeners for the Check-On-Open support
86+
final IWorkbench workbench = PlatformUI.getWorkbench();
87+
workbench.getDisplay().asyncExec(new Runnable() {
88+
@Override
89+
public void run() {
90+
91+
IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
92+
93+
for (IWorkbenchWindow window : windows) {
94+
95+
if (window != null) {
96+
97+
// collect open editors and have then run against Checkstyle if
98+
// appropriate
99+
Collection<IWorkbenchPartReference> parts = new HashSet<>();
100+
101+
// add already opened files to the filter
102+
// bugfix for 2923044
103+
IWorkbenchPage[] pages = window.getPages();
104+
for (IWorkbenchPage page : pages) {
105+
106+
IEditorReference[] editorRefs = page.getEditorReferences();
107+
Collections.addAll(parts, editorRefs);
108+
}
109+
110+
mPartListener.partsOpened(parts);
111+
112+
// remove listener first for safety, we don't want
113+
// register the same listener twice accidently
114+
window.getPartService().removePartListener(mPartListener);
115+
window.getPartService().addPartListener(mPartListener);
116+
}
117+
}
118+
119+
workbench.addWindowListener(mWindowListener);
120+
}
121+
});
122+
}
123+
124+
protected void registerProgressIcon() {
125+
IProgressService service = PlatformUI.getWorkbench().getProgressService();
126+
if (service == null) {
127+
return;
128+
}
129+
service.registerIconForFamily(CheckstyleUIPluginImages.CHECKSTYLE_ICON.getImageDescriptor(),
130+
AbstractCheckJob.CHECKSTYLE_JOB_FAMILY);
131+
}
132+
133+
}

net.sf.eclipsecs.ui/src/net/sf/eclipsecs/ui/CheckstyleUIPlugin.java

Lines changed: 0 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020

2121
package net.sf.eclipsecs.ui;
2222

23-
import java.util.Collection;
24-
import java.util.Collections;
25-
import java.util.HashSet;
2623
import java.util.Locale;
2724

2825
import org.eclipse.core.resources.IWorkspace;
@@ -33,20 +30,10 @@
3330
import org.eclipse.jface.dialogs.ErrorDialog;
3431
import org.eclipse.osgi.util.NLS;
3532
import org.eclipse.swt.widgets.Shell;
36-
import org.eclipse.ui.IEditorReference;
37-
import org.eclipse.ui.IWindowListener;
38-
import org.eclipse.ui.IWorkbench;
39-
import org.eclipse.ui.IWorkbenchPage;
40-
import org.eclipse.ui.IWorkbenchPartReference;
41-
import org.eclipse.ui.IWorkbenchWindow;
42-
import org.eclipse.ui.PlatformUI;
4333
import org.eclipse.ui.plugin.AbstractUIPlugin;
44-
import org.eclipse.ui.progress.IProgressService;
4534
import org.osgi.framework.BundleContext;
4635

47-
import net.sf.eclipsecs.core.jobs.AbstractCheckJob;
4836
import net.sf.eclipsecs.core.util.CheckstyleLog;
49-
import net.sf.eclipsecs.ui.properties.filter.CheckFileOnOpenPartListener;
5037

5138
/**
5239
* The main plugin class to be used in the desktop.
@@ -61,95 +48,15 @@ public class CheckstyleUIPlugin extends AbstractUIPlugin {
6148

6249
private static Boolean isEclipse3;
6350

64-
private final CheckFileOnOpenPartListener mPartListener = new CheckFileOnOpenPartListener();
65-
66-
private final IWindowListener mWindowListener = new IWindowListener() {
67-
68-
@Override
69-
public void windowOpened(IWorkbenchWindow window) {
70-
window.getPartService().addPartListener(mPartListener);
71-
}
72-
73-
@Override
74-
public void windowActivated(IWorkbenchWindow window) {
75-
}
76-
77-
@Override
78-
public void windowClosed(IWorkbenchWindow window) {
79-
window.getPartService().removePartListener(mPartListener);
80-
81-
}
82-
83-
@Override
84-
public void windowDeactivated(IWorkbenchWindow window) {
85-
}
86-
87-
};
88-
8951
/**
9052
* The constructor.
9153
*/
9254
public CheckstyleUIPlugin() {
9355
sPlugin = this;
9456
}
9557

96-
@Override
97-
public void start(BundleContext context) throws Exception {
98-
super.start(context);
99-
100-
// add listeners for the Check-On-Open support
101-
final IWorkbench workbench = PlatformUI.getWorkbench();
102-
workbench.getDisplay().asyncExec(new Runnable() {
103-
@Override
104-
public void run() {
105-
106-
IWorkbenchWindow[] windows = workbench.getWorkbenchWindows();
107-
108-
for (IWorkbenchWindow window : windows) {
109-
110-
if (window != null) {
111-
112-
// collect open editors and have then run against Checkstyle if
113-
// appropriate
114-
Collection<IWorkbenchPartReference> parts = new HashSet<>();
115-
116-
// add already opened files to the filter
117-
// bugfix for 2923044
118-
IWorkbenchPage[] pages = window.getPages();
119-
for (IWorkbenchPage page : pages) {
120-
121-
IEditorReference[] editorRefs = page.getEditorReferences();
122-
Collections.addAll(parts, editorRefs);
123-
}
124-
125-
mPartListener.partsOpened(parts);
126-
127-
// remove listener first for safety, we don't want
128-
// register the same listener twice accidently
129-
window.getPartService().removePartListener(mPartListener);
130-
window.getPartService().addPartListener(mPartListener);
131-
}
132-
}
133-
134-
workbench.addWindowListener(mWindowListener);
135-
registerProgressIcon();
136-
}
137-
});
138-
139-
}
140-
141-
protected void registerProgressIcon() {
142-
IProgressService service = PlatformUI.getWorkbench().getProgressService();
143-
if (service == null) {
144-
return;
145-
}
146-
service.registerIconForFamily(CheckstyleUIPluginImages.CHECKSTYLE_ICON.getImageDescriptor(),
147-
AbstractCheckJob.CHECKSTYLE_JOB_FAMILY);
148-
}
149-
15058
@Override
15159
public void stop(BundleContext context) throws Exception {
152-
15360
// free cached images
15461
CheckstyleUIPluginImages.clearCachedImages();
15562
super.stop(context);

0 commit comments

Comments
 (0)