[bugzilla 414935] Fixing potential deadlock on project creation by performing all UI operations asynchronously
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/repository/IntentWorkspaceRepositoryCreator.java b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/repository/IntentWorkspaceRepositoryCreator.java index 6b099ba..ebdc1be 100644 --- a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/repository/IntentWorkspaceRepositoryCreator.java +++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/repository/IntentWorkspaceRepositoryCreator.java
@@ -11,13 +11,8 @@ package org.eclipse.mylyn.docs.intent.client.ui.ide.repository; import org.eclipse.core.resources.IProject; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.Job; import org.eclipse.emf.cdo.eresource.EresourcePackage; import org.eclipse.emf.ecore.EPackage; -import org.eclipse.mylyn.docs.intent.client.ui.ide.Activator; import org.eclipse.mylyn.docs.intent.collab.common.location.IntentLocations; import org.eclipse.mylyn.docs.intent.collab.handlers.adapters.RepositoryStructurer; import org.eclipse.mylyn.docs.intent.collab.handlers.notification.RepositoryChangeNotificationFactoryHolder; @@ -68,21 +63,6 @@ } initializePackageRegistry(repository); repository.setRepositoryStructurer(structurer); - - // Step 3: register the created repository through the Intent project listener (will trigger - // launch of the expected clients) - final Job initializeIntentProjectJob = new Job("Initializing Intent project " - + ((IProject)artifact).getName()) { - @Override - protected IStatus run(IProgressMonitor monitor) { - // Doing activation inside a job workarounds the reentrant calls in the repository - // manager. - Activator.getDefault().getIntentProjectListener().handleOpenedProject((IProject)artifact); - return Status.OK_STATUS; - } - }; - initializeIntentProjectJob.setPriority(Job.DECORATE); - initializeIntentProjectJob.schedule(); return repository; } else { throw new RepositoryConnectionException("The given configuration artifact are invalid.");
diff --git a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/wizards/NewIntentProjectWizard.java b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/wizards/NewIntentProjectWizard.java index 7444265..0c12d42 100644 --- a/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/wizards/NewIntentProjectWizard.java +++ b/plugins/org.eclipse.mylyn.docs.intent.client.ui.ide/src/org/eclipse/mylyn/docs/intent/client/ui/ide/wizards/NewIntentProjectWizard.java
@@ -33,10 +33,12 @@ import org.eclipse.mylyn.docs.intent.collab.repository.Repository; import org.eclipse.mylyn.docs.intent.collab.repository.RepositoryConnectionException; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.ui.INewWizard; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; @@ -122,27 +124,17 @@ try { getContainer().run(false, false, workspaceOperation); - // Step 2 : open an editor on the created document + // Step 2 : perform UI operations (e.g. opening an intent editor on the created document try { - Repository repository = IntentRepositoryManager.INSTANCE.getRepository(page.getProjectName()); + final Repository repository = IntentRepositoryManager.INSTANCE.getRepository(page + .getProjectName()); if (repository != null) { - IntentEditorOpener.openIntentEditor(repository, false); - - // Step 3: open the getting started cheat sheet (according to preferences) - if (IntentPreferenceService - .getBoolean(IntentPreferenceConstants.SHOW_CHEAT_SHEET_ON_PROJECT_CREATION)) { - IViewPart cheatSheetView = PlatformUI.getWorkbench().getActiveWorkbenchWindow() - .getActivePage().showView("org.eclipse.ui.cheatsheets.views.CheatSheetView"); - if (cheatSheetView instanceof CheatSheetView) { - ((CheatSheetView)cheatSheetView) - .setInput("org.eclipse.mylyn.docs.intent.idoc.cheatsheet.getstarted"); + Runnable runnable = new Runnable() { + public void run() { + uiFinishOperations(repository); } - } - - // Step 4: open the project explorer view - // TODO: remove this work-around when bugzilla 365084 gets fixed - PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() - .showView("org.eclipse.ui.navigator.ProjectExplorer"); + }; + Display.getDefault().asyncExec(runnable); } } catch (RepositoryConnectionException e) { IntentUiLogger.logError(e); @@ -159,6 +151,37 @@ } /** + * Operations that can be performed asynchronously in UI Thread after performFinish() is called. + * + * @param repository + * the {@link Repository} that has been created by this wizard + */ + private void uiFinishOperations(Repository repository) { + try { + // Step 1: open an Intent editor on the created document + IntentEditorOpener.openIntentEditor(repository, false); + + // Step 2: open the getting started cheat sheet (according to preferences) + if (IntentPreferenceService + .getBoolean(IntentPreferenceConstants.SHOW_CHEAT_SHEET_ON_PROJECT_CREATION)) { + IViewPart cheatSheetView = PlatformUI.getWorkbench().getActiveWorkbenchWindow() + .getActivePage().showView("org.eclipse.ui.cheatsheets.views.CheatSheetView"); + if (cheatSheetView instanceof CheatSheetView) { + ((CheatSheetView)cheatSheetView) + .setInput("org.eclipse.mylyn.docs.intent.idoc.cheatsheet.getstarted"); + } + } + + // Step 3: open the project explorer view + // TODO: remove this work-around when bugzilla 365084 gets fixed + PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage() + .showView("org.eclipse.ui.navigator.ProjectExplorer"); + } catch (PartInitException e) { + IntentUiLogger.logError(e); + } + } + + /** * Returns the default content to associate to the Intent Document to create. * * @return the default content to associate to the Intent Document to create
diff --git a/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/repository/IntentRepositoryInitializer.java b/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/repository/IntentRepositoryInitializer.java index 989796d..7489b5f 100644 --- a/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/repository/IntentRepositoryInitializer.java +++ b/plugins/org.eclipse.mylyn.docs.intent.collab.common/src/org/eclipse/mylyn/docs/intent/collab/common/repository/IntentRepositoryInitializer.java
@@ -97,6 +97,13 @@ repositoryAdapter.closeContext(); } }); + try { + repositoryAdapter.save(); + } catch (ReadOnlyException e) { + IntentLogger.getInstance().logError(e); + } catch (SaveException e) { + IntentLogger.getInstance().logError(e); + } } /** @@ -140,9 +147,6 @@ for (EObject objectToCopy : elementsToUpload) { repositoryIntentResource.getContents().add(EcoreUtil.copy(objectToCopy)); } - - // Step : closing the session - repositoryAdapter.save(); } else { repositoryAdapter.undo(); }