Bug 492733 - Open Projects wizard scanning not cancelable

Improve progress reporting

Change-Id: I9f276c7f5ff14a56dc7cfccb2bdc8fa33567f602
Signed-off-by: Mickael Istria <mistria@redhat.com>
diff --git a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/SmartImportJob.java b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/SmartImportJob.java
index 4a34fb4..6e79981 100644
--- a/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/SmartImportJob.java
+++ b/bundles/org.eclipse.ui.ide/src/org/eclipse/ui/internal/wizards/datatransfer/SmartImportJob.java
@@ -168,9 +168,9 @@
 
 			if (directoriesToImport != null) {
 				this.deepChildrenDetection = false;
-				SubMonitor subMonitor = SubMonitor.convert(monitor,
-						directoriesToImport.size() * (configureProjects ? 2 : 1) + 1);
-				subMonitor.beginTask(DataTransferMessages.SmartImportJob_crawling, directoriesToImport.size() + 1);
+				SubMonitor loopMonitor = SubMonitor.convert(monitor,
+						DataTransferMessages.SmartImportJob_crawling,
+						directoriesToImport.size() * (configureProjects ? 3 : 2) + 1);
 				Comparator<File> rootToLeafComparator = new Comparator<File>() {
 					@Override
 					public int compare(File arg0, File arg1) {
@@ -185,17 +185,17 @@
 				directories.addAll(this.directoriesToImport);
 				SortedMap<File, IProject> leafToRootProjects = new TreeMap<>(Collections.reverseOrder(rootToLeafComparator));
 				final Set<IProject> alreadyConfiguredProjects = new HashSet<>();
-				subMonitor.worked(1);
+				loopMonitor.worked(1);
 				for (final File directoryToImport : directories) {
 					final boolean alreadyAnEclipseProject = new File(directoryToImport, IProjectDescription.DESCRIPTION_FILE_NAME).isFile();
 					try {
-						IProject newProject = toExistingOrNewProject(directoryToImport, subMonitor,
+						IProject newProject = toExistingOrNewProject(directoryToImport, loopMonitor.split(1),
 								IResource.BACKGROUND_REFRESH);
 						if (alreadyAnEclipseProject) {
 							alreadyConfiguredProjects.add(newProject);
 						}
 						leafToRootProjects.put(directoryToImport, newProject);
-						subMonitor.worked(1);
+						loopMonitor.worked(1);
 					} catch (CouldNotImportProjectException ex) {
 						Path path = new Path(directoryToImport.getAbsolutePath());
 						if (listener != null) {
@@ -207,18 +207,11 @@
 				if (configureProjects) {
 					JobGroup multiDirectoriesJobGroup = new JobGroup(
 							DataTransferMessages.SmartImportJob_configuringSelectedDirectories, 20, 1);
-					SubMonitor mon = subMonitor.split(directoriesToImport.size());
 					for (final IProject newProject : leafToRootProjects.values()) {
 						Job directoryJob = new Job(
 								NLS.bind(DataTransferMessages.SmartImportJob_configuring, newProject.getName())) {
 							@Override
 							protected IStatus run(IProgressMonitor aMonitor) {
-								SubMonitor monitor = null;
-								if (aMonitor instanceof SubMonitor) {
-									monitor = (SubMonitor) aMonitor;
-								} else {
-									monitor = SubMonitor.convert(aMonitor);
-								}
 								try {
 									importProjectAndChildrenRecursively(newProject,
 											!alreadyConfiguredProjects.contains(newProject), monitor);
@@ -235,12 +228,12 @@
 						directoryJob.setJobGroup(multiDirectoriesJobGroup);
 						directoryJob.schedule();
 					}
-					multiDirectoriesJobGroup.join(0, mon);
+					multiDirectoriesJobGroup.join(0, loopMonitor.split(leafToRootProjects.size()));
 				}
 
 
 			} else { // no specific projects included, consider only root
-				SubMonitor subMonitor = SubMonitor.convert(monitor);
+				SubMonitor subMonitor = SubMonitor.convert(monitor, 3);
 				File rootProjectFile = new File(this.rootDirectory, IProjectDescription.DESCRIPTION_FILE_NAME);
 				boolean isRootANewProject = !rootProjectFile.isFile();
 				this.rootProject = toExistingOrNewProject(this.rootDirectory, subMonitor, IResource.NONE);
@@ -325,6 +318,7 @@
 	}
 
 	private Set<IProject> searchAndImportChildrenProjectsRecursively(IContainer parentContainer, Set<IPath> directoriesToExclude, final IProgressMonitor progressMonitor) throws Exception {
+		SubMonitor subMonitor = SubMonitor.convert(progressMonitor, parentContainer.members().length);
 		for (IProject processedProjects : Collections.synchronizedSet(this.report.keySet())) {
 			if (processedProjects.getLocation().equals(parentContainer.getLocation())) {
 				return Collections.emptySet();
@@ -334,9 +328,6 @@
 		Set<IFolder> childrenToProcess = new HashSet<>();
 		final Set<IProject> res = Collections.synchronizedSet(new HashSet<IProject>());
 		for (IResource childResource : parentContainer.members()) {
-			if (progressMonitor.isCanceled()) {
-				throw new InterruptedException();
-			}
 			if (childResource.getType() == IResource.FOLDER && !childResource.isDerived()) {
 				boolean excluded = false;
 				if (directoriesToExclude != null) {
@@ -354,9 +345,6 @@
 
 		Set<CrawlFolderJob> jobs = new HashSet<>();
 		for (final IFolder childFolder : childrenToProcess) {
-			if (progressMonitor.isCanceled()) {
-				throw new InterruptedException();
-			}
 			CrawlFolderJob crawlerJob = new CrawlFolderJob(
 					NLS.bind(DataTransferMessages.SmartImportJob_crawling, childFolder.getLocation().toString()),
 					childFolder, res);
@@ -365,24 +353,24 @@
 				jobs.add(crawlerJob);
 				crawlerJob.schedule();
 			} else {
-				crawlerJob.run(progressMonitor);
+				crawlerJob.run(subMonitor);
+				subMonitor.worked(1);
 			}
 		}
 		for (CrawlFolderJob job : jobs) {
-			if (progressMonitor.isCanceled()) {
-				throw new InterruptedException();
-			}
-			job.join();
+			job.join(0, subMonitor.split(1));
 		}
+		subMonitor.done();
 		return res;
 	}
 
 	private Set<IProject> importProjectAndChildrenRecursively(IContainer container, boolean forceFullProjectCheck,
-			SubMonitor progressMonitor) throws Exception {
-		SubMonitor monitor = progressMonitor.split(1);
-		monitor.beginTask(null, ProjectConfiguratorExtensionManager.getAllExtensionLabels().size() * 2);
-		progressMonitor.setTaskName(NLS.bind(DataTransferMessages.SmartImportJob_inspecting,
-				container.getLocation().toFile().getAbsolutePath()));
+			IProgressMonitor progressMonitor) throws Exception {
+		int allWork = 30 + ProjectConfiguratorExtensionManager.getAllExtensionLabels().size() * 5;
+		SubMonitor subMonitor = SubMonitor.convert(progressMonitor,
+				NLS.bind(DataTransferMessages.SmartImportJob_inspecting,
+						container.getLocation().toFile().getAbsolutePath()),
+				allWork);
 		Set<IProject> projectFromCurrentContainer = new HashSet<>();
 		boolean isAlreadyAnEclipseProject = false;
 		Set<ProjectConfigurator> mainProjectConfigurators = new HashSet<>();
@@ -395,7 +383,7 @@
 		container.refreshLocal(IResource.DEPTH_INFINITE, progressMonitor);
 		if (!forceFullProjectCheck) {
 			EclipseProjectConfigurator eclipseProjectConfigurator = new EclipseProjectConfigurator();
-			if (eclipseProjectConfigurator.shouldBeAnEclipseProject(container, monitor)) {
+			if (eclipseProjectConfigurator.shouldBeAnEclipseProject(container, subMonitor.split(1))) {
 				isAlreadyAnEclipseProject = true;
 			}
 		}
@@ -407,19 +395,16 @@
 		Set<ProjectConfigurator> potentialSecondaryConfigurators = new HashSet<>();
 		IProject project = null;
 		for (ProjectConfigurator configurator : activeConfigurators) {
-			if (monitor.isCanceled()) {
-				return null;
-			}
 			// exclude Eclipse project configurator for root project if is new
 			if (configurator instanceof EclipseProjectConfigurator && forceFullProjectCheck) {
 				continue;
 			}
-			if (configurator.shouldBeAnEclipseProject(container, monitor)) {
+			if (configurator.shouldBeAnEclipseProject(container, subMonitor.split(1))) {
 				mainProjectConfigurators.add(configurator);
 				if (project == null) {
 					// Create project
 					try {
-						project = toExistingOrNewProject(container.getLocation().toFile(), monitor,
+						project = toExistingOrNewProject(container.getLocation().toFile(), subMonitor.split(1),
 								IResource.BACKGROUND_REFRESH);
 					} catch (CouldNotImportProjectException ex) {
 						this.errors.put(container.getLocation(), ex);
@@ -433,26 +418,21 @@
 			} else {
 				potentialSecondaryConfigurators.add(configurator);
 			}
-			monitor.worked(1);
 		}
 
 		if (!mainProjectConfigurators.isEmpty()) {
-			project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
+			project.refreshLocal(IResource.DEPTH_INFINITE, subMonitor.split(1));
 		}
-		monitor.setWorkRemaining(activeConfigurators.size());
 		for (ProjectConfigurator configurator : mainProjectConfigurators) {
-			if (monitor.isCanceled()) {
-				throw new InterruptedException();
-			}
+			IProgressMonitor childMonitor = subMonitor.split(1);
 			if (configurator instanceof EclipseProjectConfigurator || !isAlreadyAnEclipseProject || this.reconfigureEclipseProjects) {
-				configurator.configure(project, excludedPaths, monitor);
+				configurator.configure(project, excludedPaths, childMonitor);
 				this.report.get(project).add(configurator);
 				if (this.listener != null) {
 					listener.projectConfigured(project, configurator);
 				}
 			}
-			excludedPaths.addAll(toPathSet(configurator.getFoldersToIgnore(project, monitor)));
-			monitor.worked(1);
+			excludedPaths.addAll(toPathSet(configurator.getFoldersToIgnore(project, subMonitor.split(20))));
 		}
 
 		Set<IProject> allNestedProjects = new HashSet<>();
@@ -467,7 +447,8 @@
 			if (project == null) {
 				// Create project
 				try {
-					project = toExistingOrNewProject(container.getLocation().toFile(), progressMonitor, IResource.BACKGROUND_REFRESH);
+					project = toExistingOrNewProject(container.getLocation().toFile(), subMonitor.split(1),
+							IResource.BACKGROUND_REFRESH);
 				} catch (CouldNotImportProjectException ex) {
 					this.errors.put(container.getLocation(), ex);
 					if (this.listener != null) {
@@ -477,29 +458,23 @@
 				}
 				projectFromCurrentContainer.add(project);
 			}
-			project.refreshLocal(IResource.DEPTH_ONE, monitor); // At least one,
-																// maybe
-																// INFINITE is
-																// necessary
-			progressMonitor.beginTask(
-					NLS.bind(DataTransferMessages.SmartImportJob_continuingConfiguration, project.getName()),
-					potentialSecondaryConfigurators.size());
+			project.refreshLocal(IResource.DEPTH_ONE, subMonitor.split(1));
+			// At least depth one, maybe INFINITE is necessary
+			progressMonitor.setTaskName(
+					NLS.bind(DataTransferMessages.SmartImportJob_continuingConfiguration, project.getName()));
 			for (ProjectConfigurator additionalConfigurator : potentialSecondaryConfigurators) {
-				if (progressMonitor.isCanceled()) {
-					throw new InterruptedException();
-				}
-				if (additionalConfigurator.canConfigure(project, excludedPaths, progressMonitor)) {
-					additionalConfigurator.configure(project, excludedPaths, monitor);
+				if (additionalConfigurator.canConfigure(project, excludedPaths, subMonitor.split(1))) {
+					additionalConfigurator.configure(project, excludedPaths, subMonitor.split(1));
 					this.report.get(project).add(additionalConfigurator);
 					if (this.listener != null) {
 						listener.projectConfigured(project, additionalConfigurator);
 					}
-					excludedPaths.addAll(toPathSet(additionalConfigurator.getFoldersToIgnore(project, monitor)));
+					excludedPaths
+							.addAll(toPathSet(additionalConfigurator.getFoldersToIgnore(project, subMonitor.split(1))));
 				}
-				monitor.worked(1);
 			}
 		}
-		monitor.setWorkRemaining(0);
+		subMonitor.done();
 		return projectFromCurrentContainer;
 	}
 
@@ -523,17 +498,15 @@
 	 */
 	private IProject toExistingOrNewProject(File directory, IProgressMonitor progressMonitor, int refreshMode) throws CouldNotImportProjectException {
 		try {
-			progressMonitor.setTaskName(NLS.bind(DataTransferMessages.SmartImportJob_importingProjectIntoWorkspace,
-					directory.getAbsolutePath()));
+			SubMonitor subMonitor = SubMonitor.convert(progressMonitor, NLS.bind(
+					DataTransferMessages.SmartImportJob_importingProjectIntoWorkspace, directory.getAbsolutePath()), 2);
 			IProject project = projectAlreadyExistsInWorkspace(directory);
 			if (project == null) {
-				project = createOrImportProject(directory, progressMonitor);
+				project = createOrImportProject(directory, subMonitor.split(1));
 			}
+			subMonitor.setWorkRemaining(1);
 
-			if (progressMonitor.isCanceled()) {
-				return null;
-			}
-			project.open(refreshMode, progressMonitor);
+			project.open(refreshMode, subMonitor.split(1));
 			if (!this.report.containsKey(project)) {
 				this.report.put(project, new ArrayList<ProjectConfigurator>());
 			}
@@ -632,10 +605,11 @@
 			}
 			List<ProjectConfigurator> activeConfigurators = configurationManager
 					.getAllActiveProjectConfigurators(this.rootDirectory);
+			SubMonitor loopMonitor = SubMonitor.convert(monitor, activeConfigurators.size());
 			for (ProjectConfigurator configurator : activeConfigurators) {
 				Set<File> supportedDirectories = configurator.findConfigurableLocations(
 						SmartImportJob.this.rootDirectory,
-						monitor);
+						loopMonitor.split(1));
 				if (supportedDirectories != null) {
 					for (File supportedFile : supportedDirectories) {
 						if (!res.containsKey(supportedFile)) {