From 3b9e42f946dc2b5560a86f3895492938e1e3fcc7 Mon Sep 17 00:00:00 2001 From: Fred Bricon Date: Fri, 25 Apr 2014 21:34:59 +0200 Subject: 433525 : Fix background archetype retrieval Archetype retrieval job is now cancelled every time the catalog changes or the user goes to the next page. The selected archetype variable is only updated if the job finishes while on the same page, to avoid updating disposed widgets or the current archetype while another page is displayed. Bug 433525 Change-Id: Id78104ce2ec1aed0fd090220ee98cf1b941b5396 Signed-off-by: Fred Bricon --- .../org/eclipse/m2e/core/ui/internal/Messages.java | 6 +- .../m2e/core/ui/internal/messages.properties | 4 +- .../wizards/MavenProjectWizardArchetypePage.java | 172 ++++++++++++--------- 3 files changed, 108 insertions(+), 74 deletions(-) diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java index 93fe1841..0564efaa 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/Messages.java @@ -409,7 +409,9 @@ public class Messages extends NLS { public static String MavenProjectWizardArchetypePage_btnSnapshots; - public static String MavenProjectWizardArchetypePage_error_no; + public static String MavenProjectWizardArchetypePage_error_emptyNexusIndexer; + + public static String MavenProjectWizardArchetypePage_error_emptyCatalog; public static String MavenProjectWizardArchetypePage_error_read; @@ -417,6 +419,8 @@ public class Messages extends NLS { public static String MavenProjectWizardArchetypePage_error_resolve2; + public static String MavenProjectWizardArchetypePage_ErrorRetrievingArchetypes; + public static String MavenProjectWizardArchetypePage_lblCatalog; public static String MavenProjectWizardArchetypePage_lblFilter; diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties index 33a6a82d..25525786 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/messages.properties @@ -236,10 +236,12 @@ MavenProjectWizardArchetypePage_btnAdd=&Add Archetype... MavenProjectWizardArchetypePage_btnConfigure=&Configure... MavenProjectWizardArchetypePage_btnLast=&Show the last version of Archetype only MavenProjectWizardArchetypePage_btnSnapshots=&Include snapshot archetypes -MavenProjectWizardArchetypePage_error_no=No archetypes currently available. The archetype list will refresh when the indexes finish updating. +MavenProjectWizardArchetypePage_error_emptyNexusIndexer=No archetypes currently available. The archetype list will refresh when the indexes finish updating. +MavenProjectWizardArchetypePage_error_emptyCatalog=No archetypes available for this catalog. MavenProjectWizardArchetypePage_error_read=Unable to read catalog factory. MavenProjectWizardArchetypePage_error_resolve=The archetype {0} could not be resolved. MavenProjectWizardArchetypePage_error_resolve2=Can't resolve Archetype {0} +MavenProjectWizardArchetypePage_ErrorRetrievingArchetypes=Error retrieving archetypes MavenProjectWizardArchetypePage_lblCatalog=Ca&talog\: MavenProjectWizardArchetypePage_lblFilter=&Filter\: MavenProjectWizardArchetypePage_task_downloading=Downloading Archetype diff --git a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypePage.java b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypePage.java index e8dbb428..ffea9935 100644 --- a/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypePage.java +++ b/org.eclipse.m2e.core.ui/src/org/eclipse/m2e/core/ui/internal/wizards/MavenProjectWizardArchetypePage.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008-2010 Sonatype, Inc. + * Copyright (c) 2008-2014 Sonatype, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -29,8 +29,11 @@ import org.slf4j.LoggerFactory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.ComboViewer; import org.eclipse.jface.viewers.IElementComparer; @@ -95,6 +98,7 @@ import org.eclipse.m2e.core.internal.index.IndexListener; import org.eclipse.m2e.core.internal.index.IndexManager; import org.eclipse.m2e.core.project.ProjectImportConfiguration; import org.eclipse.m2e.core.repository.IRepository; +import org.eclipse.m2e.core.ui.internal.M2EUIPluginActivator; import org.eclipse.m2e.core.ui.internal.Messages; import org.eclipse.m2e.core.ui.internal.util.M2EUIUtils; @@ -170,6 +174,8 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp ArchetypeCatalogFactory catalogFactory = null; + private RetrievingArchetypesJob job; + /** * Default constructor. Sets the title and description of this wizard page and marks it as not being complete as user * input is required for continuing. @@ -507,30 +513,45 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp } public void dispose() { + if(job != null) { + job.cancel(); + job = null; + } MavenPlugin.getIndexManager().removeIndexListener(this); super.dispose(); } public List getArchetypesForCatalog() { - if(catalogFactory == null) { - return getAllArchetypes(); - } try { - return catalogFactory.getArchetypeCatalog().getArchetypes(); - + return getArchetypesForCatalog(catalogFactory, null); } catch(CoreException ce) { setErrorMessage(org.eclipse.m2e.core.ui.internal.Messages.MavenProjectWizardArchetypePage_error_read); return null; } } + public static List getArchetypesForCatalog(ArchetypeCatalogFactory archCatalogFactory, + IProgressMonitor monitor) throws CoreException { + if(archCatalogFactory == null) { + return getAllArchetypes(monitor); + } + return archCatalogFactory.getArchetypeCatalog().getArchetypes(); + } + @SuppressWarnings("unchecked") - private List getAllArchetypes() { + private static List getAllArchetypes(IProgressMonitor monitor) { ArchetypeManager manager = MavenPluginActivator.getDefault().getArchetypeManager(); Collection archetypeCatalogs = manager.getArchetypeCatalogs(); ArrayList list = new ArrayList(); + if(monitor == null) { + monitor = new NullProgressMonitor(); + } + for(ArchetypeCatalogFactory catalog : archetypeCatalogs) { + if(monitor.isCanceled()) { + return Collections.emptyList(); + } try { //temporary hack to get around 'Test Remote Catalog' blowing up on download //described in https://issues.sonatype.org/browse/MNGECLIPSE-1792 @@ -551,46 +572,50 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp /** Loads the available archetypes. */ void loadArchetypes(final String groupId, final String artifactId, final String version) { - Job job = new Job(Messages.wizardProjectPageArchetypeRetrievingArchetypes) { - protected IStatus run(IProgressMonitor monitor) { - try { - List catalogArchetypes = getArchetypesForCatalog(); + if(job != null) { + job.cancel(); + } + job = new RetrievingArchetypesJob(catalogFactory); + job.addJobChangeListener(new JobChangeAdapter() { + public void done(IJobChangeEvent event) { - if(catalogArchetypes == null || catalogArchetypes.size() == 0) { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - if(catalogFactory != null && "Nexus Indexer".equals(catalogFactory.getDescription())) { //$NON-NLS-1$ - setErrorMessage(org.eclipse.m2e.core.ui.internal.Messages.MavenProjectWizardArchetypePage_error_no); - } - } - }); + final RetrievingArchetypesJob thisJob = (RetrievingArchetypesJob) event.getJob(); + if(IStatus.CANCEL == event.getResult().getSeverity() || !isCurrentPage()) { + return; + } + List catalogArchetypes = thisJob.catalogArchetypes; + + final String error; + if(IStatus.ERROR == event.getResult().getSeverity()) { + error = event.getResult().getMessage(); + } else if((catalogArchetypes == null || catalogArchetypes.isEmpty())) { + if(catalogFactory != null && "Nexus Indexer".equals(catalogFactory.getDescription())) { //$NON-NLS-1$ + error = Messages.MavenProjectWizardArchetypePage_error_emptyNexusIndexer; } else { - Display.getDefault().asyncExec(new Runnable() { - public void run() { - setErrorMessage(null); - } - }); + error = Messages.MavenProjectWizardArchetypePage_error_emptyCatalog; } - if(catalogArchetypes == null) { - return Status.CANCEL_STATUS; + } else { + error = null; + } + + Display.getDefault().asyncExec(new Runnable() { + public void run() { + setErrorMessage(error); } - TreeSet archs = new TreeSet(ARCHETYPE_COMPARATOR); + }); + TreeSet archs = new TreeSet(ARCHETYPE_COMPARATOR); + if(catalogArchetypes != null) { archs.addAll(catalogArchetypes); - archetypes = archs; - - Display.getDefault().asyncExec(new Runnable() { - public void run() { - updateViewer(groupId, artifactId, version); - } - }); - } catch(Exception e) { - monitor.done(); - return Status.CANCEL_STATUS; } + archetypes = archs; - return Status.OK_STATUS; + Display.getDefault().asyncExec(new Runnable() { + public void run() { + updateViewer(groupId, artifactId, version); + } + }); } - }; + }); job.schedule(); } @@ -664,6 +689,11 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp if(selected != null) { viewer.reveal(selected); } + } else { + if(job != null) { + job.cancel(); + job = null; + } } } @@ -673,11 +703,17 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp } void updateViewer(String groupId, String artifactId, String version) { + if(viewer.getControl().isDisposed()) { + return; + } + archetypeVersions = getArchetypeVersions(archetypes); viewer.setInput(archetypes); - selectArchetype(groupId, artifactId, version); + if(isCurrentPage()) { + selectArchetype(groupId, artifactId, version); + } Table table = viewer.getTable(); int columnCount = table.getColumnCount(); @@ -916,37 +952,6 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp } } - /** - * @deprecated this class is not used and will be removed from 1.1 - */ - protected class IncludeSnapshotsFilter extends ViewerFilter implements SelectionListener { - public boolean select(Viewer viewer, Object parentElement, Object element) { - return true; - } - - public void widgetSelected(SelectionEvent e) { - } - - public void widgetDefaultSelected(SelectionEvent e) { - } - } - - /** - * @deprecated this class is not used and will be removed from 1.1 - */ - protected class LastVersionFilter extends ViewerFilter implements SelectionListener { - - public boolean select(Viewer viewer, Object parentElement, Object element) { - return true; - } - - public void widgetSelected(SelectionEvent e) { - } - - public void widgetDefaultSelected(SelectionEvent e) { - } - } - protected class VersionsFilter extends ViewerFilter implements SelectionListener { private boolean showLastVersion; @@ -996,7 +1001,7 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp } boolean isSnapshotVersion(String version) { - return !M2EUIUtils.nullOrEmpty(version) && version.endsWith("SNAPSHOT"); + return !M2EUIUtils.nullOrEmpty(version) && version.endsWith("SNAPSHOT"); //$NON-NLS-1$ } public void widgetSelected(SelectionEvent e) { @@ -1063,4 +1068,27 @@ public class MavenProjectWizardArchetypePage extends AbstractMavenWizardPage imp public void indexUpdating(IRepository repository) { } + private static class RetrievingArchetypesJob extends Job { + + List catalogArchetypes; + + private ArchetypeCatalogFactory archetypeCatalogFactory; + + public RetrievingArchetypesJob(ArchetypeCatalogFactory catalogFactory) { + super(Messages.wizardProjectPageArchetypeRetrievingArchetypes); + this.archetypeCatalogFactory = catalogFactory; + } + + protected IStatus run(IProgressMonitor monitor) { + try { + catalogArchetypes = getArchetypesForCatalog(archetypeCatalogFactory, monitor); + } catch(Exception e) { + monitor.done(); + return new Status(IStatus.ERROR, M2EUIPluginActivator.PLUGIN_ID, + Messages.MavenProjectWizardArchetypePage_ErrorRetrievingArchetypes, e); + } + return monitor.isCanceled() ? Status.CANCEL_STATUS : Status.OK_STATUS; + } + + } } -- cgit v1.2.3