Bug 477579 - Improve bundle activator start using asynchronous
initialization
- asynchronous initialization of TemplateStore
- create TemplateStoreInitializer
- asynchronous initialization of MemberOrderReferenceCache
Change-Id: Ib92289b930ad194bcf78aa28dfa893ae650e9417
Signed-off-by: Mark Hoffmann <mark.hoffmann@web.de>
diff --git a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
index e171527..312bc20 100644
--- a/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
+++ b/org.eclipse.jdt.ui/META-INF/MANIFEST.MF
@@ -142,3 +142,5 @@
com.ibm.icu;bundle-version="4.4.2",
org.eclipse.equinox.bidi;bundle-version="[0.10.0,2.0.0)"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Import-Package: org.osgi.util.function;version="1.1.0",
+ org.osgi.util.promise;version="1.1.0"
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/JavaPlugin.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/JavaPlugin.java
index 8d576a2..ea48d98 100644
--- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/JavaPlugin.java
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/JavaPlugin.java
@@ -14,9 +14,11 @@
package org.eclipse.jdt.internal.ui;
import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.concurrent.Executors;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -24,6 +26,8 @@
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.packageadmin.PackageAdmin;
import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.util.promise.Promise;
+import org.osgi.util.promise.PromiseFactory;
import org.eclipse.osgi.service.debug.DebugOptions;
import org.eclipse.osgi.service.debug.DebugOptionsListener;
@@ -144,21 +148,13 @@
* @since 3.0
*/
private static final String TEMPLATES_KEY= "org.eclipse.jdt.ui.text.custom_templates"; //$NON-NLS-1$
- /**
- * The key to store customized code templates.
- * @since 3.0
- */
- private static final String CODE_TEMPLATES_KEY= "org.eclipse.jdt.ui.text.custom_code_templates"; //$NON-NLS-1$
+
/**
* The key to store whether the legacy templates have been migrated
* @since 3.0
*/
private static final String TEMPLATES_MIGRATION_KEY= "org.eclipse.jdt.ui.text.templates_migrated"; //$NON-NLS-1$
- /**
- * The key to store whether the legacy code templates have been migrated
- * @since 3.0
- */
- private static final String CODE_TEMPLATES_MIGRATION_KEY= "org.eclipse.jdt.ui.text.code_templates_migrated"; //$NON-NLS-1$
+
public static boolean DEBUG_AST_PROVIDER;
@@ -209,6 +205,8 @@
private WorkingCopyManager fWorkingCopyManager;
+ private TemplateStoreInitializer fJavaPluginInitializer;
+
/**
* @deprecated to avoid deprecation warning
*/
@@ -221,6 +219,7 @@
private ImageDescriptorRegistry fImageDescriptorRegistry;
private MembersOrderPreferenceCache fMembersOrderPreferenceCache;
+ private Promise<MembersOrderPreferenceCache> fMembersOrderPreferenceCachePromise;
private JavaEditorTextHoverDescriptor[] fJavaEditorTextHoverDescriptors;
@@ -305,11 +304,11 @@
}
public static Shell getActiveWorkbenchShell() {
- IWorkbenchWindow window= getActiveWorkbenchWindow();
- if (window != null) {
- return window.getShell();
- }
- return null;
+ IWorkbenchWindow window= getActiveWorkbenchWindow();
+ if (window != null) {
+ return window.getShell();
+ }
+ return null;
}
public static String getPluginId() {
@@ -370,7 +369,7 @@
public JavaPlugin() {
super();
- fgJavaPlugin = this;
+ fgJavaPlugin= this;
}
/* (non - Javadoc)
@@ -401,11 +400,10 @@
// by the MembersOrderPreferenceCache common logic
JavaManipulation.setPreferenceNodeId(getPluginId());
- IPreferenceStore store= getPreferenceStore();
+ PromiseFactory promiseFactory= new PromiseFactory(Executors.newSingleThreadExecutor());
+ fMembersOrderPreferenceCachePromise= promiseFactory.submit(this::createMemberOrderPreferenceCache);
// must add here to guarantee that it is the first in the listener list
- fMembersOrderPreferenceCache= new MembersOrderPreferenceCache();
- fMembersOrderPreferenceCache.install(store);
FormatterProfileStore.checkCurrentOptionsVersion();
@@ -431,9 +429,7 @@
new InitializeAfterLoadJob().schedule(); // last call in start, see bug 191193
}
-
- JavaManipulation.setCodeTemplateStore(getCodeTemplateStore());
- JavaManipulation.setCodeTemplateContextRegistry(getCodeTemplateContextRegistry());
+ getTemplateStoreInitializer();
}
private void createOrUpdateWorkingSet(String name, String oldname, String label, final String id) {
@@ -450,7 +446,7 @@
workingSet.setLabel(label);
} else {
logErrorMessage("found existing workingset with name=\"" + name + "\" but id=\"" + workingSet.getId() + "\""); //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
- }
+ }
}
IWorkingSet oldWorkingSet= workingSetManager.getWorkingSet(oldname);
if (oldWorkingSet != null && id.equals(oldWorkingSet.getId())) {
@@ -570,8 +566,21 @@
}
/**
+ * Creates an additional async initializer that loads the template store. Because the initialization
+ * can be 'long running', it is not recommended to be executed in the bundle activator.
+ *
+ * @return the initializer instance
+ */
+ private synchronized TemplateStoreInitializer getTemplateStoreInitializer() {
+ if (fJavaPluginInitializer == null) {
+ fJavaPluginInitializer= new TemplateStoreInitializer();
+ fJavaPluginInitializer.activate();
+ }
+ return fJavaPluginInitializer;
+ }
+
+ /**
* Private deprecated method to avoid deprecation warnings
- *
* @return the deprecated buffer factory
* @deprecated to avoid deprecation warnings
*/
@@ -629,7 +638,7 @@
/**
* Returns the Java Core plug-in preferences.
- *
+ *
* @return the Java Core plug-in preferences
* @since 3.7
*/
@@ -651,11 +660,29 @@
}
public synchronized MembersOrderPreferenceCache getMemberOrderPreferenceCache() {
+ if (fMembersOrderPreferenceCache == null) {
+ try {
+ fMembersOrderPreferenceCache= fMembersOrderPreferenceCachePromise.getValue();
+ } catch (InvocationTargetException | InterruptedException e) {
+ if(e instanceof InterruptedException){
+ Thread.currentThread().interrupt();
+ }
+ log(e);
+ fMembersOrderPreferenceCache= createMemberOrderPreferenceCache();
+ }
+ }
// initialized on startup
return fMembersOrderPreferenceCache;
}
+ private MembersOrderPreferenceCache createMemberOrderPreferenceCache() {
+ IPreferenceStore store= getPreferenceStore();
+ MembersOrderPreferenceCache cache= new MembersOrderPreferenceCache();
+ cache.install(store);
+ return cache;
+ }
+
public synchronized TypeFilter getTypeFilter() {
if (fTypeFilter == null)
fTypeFilter= new TypeFilter();
@@ -818,7 +845,7 @@
/**
* Private deprecated method to avoid deprecation warnings
- *
+ *
* @return the deprecated template store
* @deprecated to avoid deprecation warnings
*/
@@ -853,27 +880,17 @@
*/
public TemplateStore getCodeTemplateStore() {
if (fCodeTemplateStore == null) {
- IPreferenceStore store= getPreferenceStore();
- boolean alreadyMigrated= store.getBoolean(CODE_TEMPLATES_MIGRATION_KEY);
- if (alreadyMigrated)
- fCodeTemplateStore= new ContributionTemplateStore(getCodeTemplateContextRegistry(), store, CODE_TEMPLATES_KEY);
- else {
- fCodeTemplateStore= new CompatibilityTemplateStore(getCodeTemplateContextRegistry(), store, CODE_TEMPLATES_KEY, getOldCodeTemplateStoreInstance());
- store.setValue(CODE_TEMPLATES_MIGRATION_KEY, true);
- }
-
+ TemplateStoreInitializer initializer= getTemplateStoreInitializer();
+ Promise<TemplateStore> p= initializer.getCodeTemplateStore();
try {
- fCodeTemplateStore.load();
- } catch (IOException e) {
+ fCodeTemplateStore= p.getValue();
+ } catch (InvocationTargetException | InterruptedException e) {
+ if(e instanceof InterruptedException){
+ Thread.currentThread().interrupt();
+ }
+ fCodeTemplateStore= initializer.loadCodeTemplateStore();
log(e);
}
-
- fCodeTemplateStore.startListeningForPreferenceChanges();
-
- // compatibility / bug fixing code for duplicated templates
- // TODO remove for 3.0
- CompatibilityTemplateStore.pruneDuplicates(fCodeTemplateStore, true);
-
}
return fCodeTemplateStore;
@@ -881,12 +898,12 @@
/**
* Private deprecated method to avoid deprecation warnings
- *
+ *
* @return the deprecated code template store
* @deprecated to avoid deprecation warnings
*/
@Deprecated
- private org.eclipse.jdt.internal.corext.template.java.CodeTemplates getOldCodeTemplateStoreInstance() {
+ org.eclipse.jdt.internal.corext.template.java.CodeTemplates getOldCodeTemplateStoreInstance() {
return org.eclipse.jdt.internal.corext.template.java.CodeTemplates.getInstance();
}
@@ -913,7 +930,7 @@
/**
* Flushes the instance scope of this plug-in.
- *
+ *
* @since 3.7
*/
public static void flushInstanceScope() {
@@ -927,7 +944,7 @@
/**
* Returns the registry of the extensions to the
* <code>org.eclipse.jdt.ui.javaFoldingStructureProvider</code> extension point.
- *
+ *
* @return the registry of contributed <code>IJavaFoldingStructureProvider</code>
* @since 3.0
*/
@@ -1022,7 +1039,7 @@
* Returns the content assist additional info focus affordance string.
*
* @return the affordance string which is <code>null</code> if the
- * preference is disabled
+ * preference is disabled
*
* @see EditorsUI#getTooltipAffordanceString()
* @since 3.4
diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/TemplateStoreInitializer.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/TemplateStoreInitializer.java
new file mode 100644
index 0000000..9734183
--- /dev/null
+++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/internal/ui/TemplateStoreInitializer.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2018 IBM Corporation and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.internal.ui;
+
+import java.io.IOException;
+import java.util.concurrent.Executors;
+
+import org.osgi.util.promise.Promise;
+import org.osgi.util.promise.PromiseFactory;
+
+import org.eclipse.jface.preference.IPreferenceStore;
+
+import org.eclipse.jface.text.templates.persistence.TemplateStore;
+
+import org.eclipse.ui.editors.text.templates.ContributionTemplateStore;
+
+import org.eclipse.jdt.core.manipulation.JavaManipulation;
+
+/**
+ * Initializer for the template store.
+ *
+ */
+public class TemplateStoreInitializer {
+
+ /**
+ * The key to store customized code templates.
+ */
+ private static final String CODE_TEMPLATES_KEY= "org.eclipse.jdt.ui.text.custom_code_templates"; //$NON-NLS-1$
+
+ /**
+ * The key to store whether the legacy code templates have been migrated
+ */
+ private static final String CODE_TEMPLATES_MIGRATION_KEY= "org.eclipse.jdt.ui.text.code_templates_migrated"; //$NON-NLS-1$
+
+ private volatile Promise<TemplateStore> fCodeTemplateStore;
+
+ public void activate() {
+ fCodeTemplateStore = loadTemplateStoreAsync();
+ }
+
+ /**
+ * Returns the promise for the template store
+ * @return the promise for the template store
+ */
+ public Promise<TemplateStore> getCodeTemplateStore() {
+ return fCodeTemplateStore;
+ }
+
+ /**
+ * Loads the template store asynchronous. It returns a promise that is either resolved
+ * or not, when an error occurs. In that case
+ * @return a promise of the template store, that is either resolved or not ()
+ */
+ private Promise<TemplateStore> loadTemplateStoreAsync() {
+ PromiseFactory pf = new PromiseFactory(Executors.newSingleThreadExecutor());
+ Promise<TemplateStore> promise = pf.submit(this::loadCodeTemplateStore);
+ // set all template store data, when promise is resolved and logs, if an exception occurs
+ return promise.onFailure(JavaPlugin::log);
+ }
+
+ /**
+ * Sets the template store information
+ * @param templateStore the template store instance
+ */
+ private void setTemplateStore(TemplateStore templateStore) {
+ JavaManipulation.setCodeTemplateStore(templateStore);
+ JavaManipulation.setCodeTemplateContextRegistry(JavaPlugin.getDefault().getCodeTemplateContextRegistry());
+ }
+
+ /**
+ * Loads the template store data
+ * @return the template store
+ */
+ public TemplateStore loadCodeTemplateStore() {
+ JavaPlugin javaPlugin= JavaPlugin.getDefault();
+ IPreferenceStore store= javaPlugin.getPreferenceStore();
+ boolean alreadyMigrated= store.getBoolean(CODE_TEMPLATES_MIGRATION_KEY);
+ TemplateStore templateStore;
+ if (alreadyMigrated) {
+ templateStore= new ContributionTemplateStore(javaPlugin.getCodeTemplateContextRegistry(), store, CODE_TEMPLATES_KEY);
+ } else {
+ templateStore= new CompatibilityTemplateStore(javaPlugin.getCodeTemplateContextRegistry(), store, CODE_TEMPLATES_KEY, javaPlugin.getOldCodeTemplateStoreInstance());
+ store.setValue(CODE_TEMPLATES_MIGRATION_KEY, true);
+ }
+
+ try {
+ templateStore.load();
+ } catch (IOException e) {
+ JavaPlugin.log(e);
+ }
+
+ templateStore.startListeningForPreferenceChanges();
+
+ // compatibility / bug fixing code for duplicated templates
+ // TODO remove for 3.0
+ CompatibilityTemplateStore.pruneDuplicates(templateStore, true);
+ setTemplateStore(templateStore);
+ return templateStore;
+ }
+
+}