View | Details | Raw Unified | Return to bug 175849 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java (-7 / +16 lines)
Lines 815-821 Link Here
815
815
816
/* 
816
/* 
817
 * Ensures that no resource deta is reported if a container is initialized right after startup  to the same value it had before shutdown.
817
 * Ensures that no resource deta is reported if a container is initialized right after startup  to the same value it had before shutdown.
818
 * (regression test for bug )
818
 * (regression test for bug 175849 Project is touched on restart)
819
 */
819
 */
820
public void testContainerInitializer17() throws CoreException {
820
public void testContainerInitializer17() throws CoreException {
821
	IResourceChangeListener listener = new IResourceChangeListener() {
821
	IResourceChangeListener listener = new IResourceChangeListener() {
Lines 836-854 Link Here
836
				new String[] {}, 
836
				new String[] {}, 
837
				new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, 
837
				new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, 
838
				"");
838
				"");
839
				
839
		ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P3", "/P1/lib.jar"}));
840
		createJavaProject(
841
				"P3", 
842
				new String[] {}, 
843
				new String[] {"org.eclipse.jdt.core.tests.model.TEST_CONTAINER"}, 
844
				"");
840
				
845
				
841
		// simulate state on startup
846
		// simulate state on startup
842
		simulateExitRestart();
847
		simulateExitRestart();
843
		
848
		
844
		getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
849
		getWorkspace().addResourceChangeListener(listener, IResourceChangeEvent.POST_CHANGE);
845
		
850
		
846
		// simulate concurrency (another thread is initializing all containers in parallel and thus this flag is set to false)
847
		JavaModelManager.getJavaModelManager().deltaState.rootsAreStale = false;
848
		
849
		// initialize to the same value
851
		// initialize to the same value
850
		ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"}));
852
		ContainerInitializer.setInitializer(new DefaultContainerInitializer(new String[] {"P2", "/P1/lib.jar"}) {
851
		ContainerInitializer.initializer.initialize(new Path("org.eclipse.jdt.core.tests.model.TEST_CONTAINER"), p2);
853
	        public void initialize(IPath containerPath, IJavaProject project) throws CoreException {
854
	        	// simulate concurrency (another thread is initializing all containers in parallel and thus this flag is set to true)
855
	        	JavaModelManager.getJavaModelManager().batchContainerInitializations = true;
856
	            super.initialize(containerPath, project);
857
	        }
858
		});
859
		p2.getResolvedClasspath(true);
852
860
853
		assertEquals(
861
		assertEquals(
854
			"Unexpected resource delta on container initialization", 
862
			"Unexpected resource delta on container initialization", 
Lines 859-864 Link Here
859
		getWorkspace().removeResourceChangeListener(listener);
867
		getWorkspace().removeResourceChangeListener(listener);
860
		deleteProject("P1");
868
		deleteProject("P1");
861
		deleteProject("P2");
869
		deleteProject("P2");
870
		deleteProject("P3");
862
	}
871
	}
863
}
872
}
864
873
(-)model/org/eclipse/jdt/internal/core/SetVariablesOperation.java (-18 / +1 lines)
Lines 51-57 Link Here
51
			}
51
			}
52
			
52
			
53
			JavaModelManager manager = JavaModelManager.getJavaModelManager();
53
			JavaModelManager manager = JavaModelManager.getJavaModelManager();
54
			if (variablePutIfInitializingWithSameValue(manager))
54
			if (manager.variablePutIfInitializingWithSameValue(this.variableNames, this.variablePaths))
55
				return;
55
				return;
56
	
56
	
57
			int varLength = this.variableNames.length;
57
			int varLength = this.variableNames.length;
Lines 179-199 Link Here
179
		}
179
		}
180
	}
180
	}
181
181
182
	/*
183
	 * Optimize startup case where 1 variable is initialized at a time with the same value as on shutdown.
184
	 */
185
	private boolean variablePutIfInitializingWithSameValue(JavaModelManager manager) {
186
		if (this.variableNames.length != 1)
187
			return false;
188
		String variableName = this.variableNames[0];
189
		IPath oldPath = manager.getPreviousSessionVariable(variableName);
190
		if (oldPath == null)
191
			return false;
192
		IPath newPath = this.variablePaths[0];
193
		if (!oldPath.equals(newPath))
194
			return false;
195
		manager.variablePut(variableName, newPath);
196
		return true;
197
	}
198
199
}
182
}
(-)model/org/eclipse/jdt/internal/core/JavaModelManager.java (-34 / +82 lines)
Lines 426-433 Link Here
426
426
427
	public synchronized IClasspathContainer containerGet(IJavaProject project, IPath containerPath) {	
427
	public synchronized IClasspathContainer containerGet(IJavaProject project, IPath containerPath) {	
428
		// check initialization in progress first
428
		// check initialization in progress first
429
		HashSet projectInitializations = containerInitializationInProgress(project);
429
		if (containerIsInitializationInProgress(project, containerPath)) {
430
		if (projectInitializations.contains(containerPath)) {
431
			return CONTAINER_INITIALIZATION_IN_PROGRESS;
430
			return CONTAINER_INITIALIZATION_IN_PROGRESS;
432
		}
431
		}
433
		
432
		
Lines 439-444 Link Here
439
		return container;
438
		return container;
440
	}
439
	}
441
	
440
	
441
	public synchronized IClasspathContainer containerGetDefaultToPreviousSession(IJavaProject project, IPath containerPath) {	
442
		Map projectContainers = (Map)this.containers.get(project);
443
		if (projectContainers == null)
444
			return getPreviousSessionContainer(containerPath, project);
445
		IClasspathContainer container = (IClasspathContainer)projectContainers.get(containerPath);
446
		if (container == null)
447
			return getPreviousSessionContainer(containerPath, project);
448
		return container;
449
	}
450
	
442
	private synchronized Map containerClone(IJavaProject project) {
451
	private synchronized Map containerClone(IJavaProject project) {
443
		Map originalProjectContainers = (Map)this.containers.get(project);
452
		Map originalProjectContainers = (Map)this.containers.get(project);
444
		if (originalProjectContainers == null) return null;
453
		if (originalProjectContainers == null) return null;
Lines 447-475 Link Here
447
		return projectContainers;
456
		return projectContainers;
448
	}
457
	}
449
	
458
	
450
	/*
459
	private boolean containerIsInitializationInProgress(IJavaProject project, IPath containerPath) {
451
	 * Returns the set of container paths for the given project that are being initialized in the current thread.
452
	 */
453
	private HashSet containerInitializationInProgress(IJavaProject project) {
454
		Map initializations = (Map)this.containerInitializationInProgress.get();
460
		Map initializations = (Map)this.containerInitializationInProgress.get();
455
		if (initializations == null) {
461
		if (initializations == null)
456
			initializations = new HashMap();
462
			return false;
457
			this.containerInitializationInProgress.set(initializations);
463
		HashSet projectInitializations = (HashSet) initializations.get(project);
458
		}
464
		if (projectInitializations == null)
459
		HashSet projectInitializations = (HashSet)initializations.get(project);
465
			return false;
460
		if (projectInitializations == null) {
466
		return projectInitializations.contains(containerPath);
461
			projectInitializations = new HashSet();
462
			initializations.put(project, projectInitializations);
463
		}
464
		return projectInitializations;
465
	}
467
	}
466
468
469
	private void containerAddInitializationInProgress(IJavaProject project, IPath containerPath) {
470
		Map initializations = (Map)this.containerInitializationInProgress.get();
471
		if (initializations == null)
472
			this.containerInitializationInProgress.set(initializations = new HashMap());
473
		HashSet projectInitializations = (HashSet) initializations.get(project);
474
		if (projectInitializations == null)
475
			initializations.put(project, projectInitializations = new HashSet());
476
		projectInitializations.add(containerPath);
477
	}
478
	
467
	public synchronized void containerPut(IJavaProject project, IPath containerPath, IClasspathContainer container){
479
	public synchronized void containerPut(IJavaProject project, IPath containerPath, IClasspathContainer container){
468
480
469
		// set/unset the initialization in progress
481
		// set/unset the initialization in progress
470
		if (container == CONTAINER_INITIALIZATION_IN_PROGRESS) {
482
		if (container == CONTAINER_INITIALIZATION_IN_PROGRESS) {
471
			HashSet projectInitializations = containerInitializationInProgress(project);
483
			containerAddInitializationInProgress(project, containerPath);
472
			projectInitializations.add(containerPath);
473
			
484
			
474
			// do not write out intermediate initialization value
485
			// do not write out intermediate initialization value
475
			return;
486
			return;
Lines 507-515 Link Here
507
		this.containers.remove(project);
518
		this.containers.remove(project);
508
	}
519
	}
509
	
520
	
510
	/*
511
	 * Optimize startup case where a container for 1 project is initialized at a time with the same entries as on shutdown.
512
	 */
513
	public boolean containerPutIfInitializingWithSameEntries(IPath containerPath, IJavaProject[] projects, IClasspathContainer[] respectiveContainers) {
521
	public boolean containerPutIfInitializingWithSameEntries(IPath containerPath, IJavaProject[] projects, IClasspathContainer[] respectiveContainers) {
514
		int projectLength = projects.length;
522
		int projectLength = projects.length;
515
		if (projectLength != 1) 
523
		if (projectLength != 1) 
Lines 518-533 Link Here
518
		if (container == null)
526
		if (container == null)
519
			return false;
527
			return false;
520
		IJavaProject project = projects[0];
528
		IJavaProject project = projects[0];
521
		IClasspathContainer previousSessionContainer = getPreviousSessionContainer(containerPath, project);
529
		// optimize only if initializing, otherwise we are in a regular setContainer(...) call
530
		if (!containerIsInitializationInProgress(project, containerPath)) 
531
			return false;
532
		IClasspathContainer previousContainer = containerGetDefaultToPreviousSession(project, containerPath);
522
		final IClasspathEntry[] newEntries = container.getClasspathEntries();
533
		final IClasspathEntry[] newEntries = container.getClasspathEntries();
523
		if (previousSessionContainer == null) 
534
		if (previousContainer == null) 
524
			if (newEntries.length == 0) {
535
			if (newEntries.length == 0) {
525
				containerPut(project, containerPath, container);
536
				containerPut(project, containerPath, container);
526
				return true;
537
				return true;
527
			} else {
538
			} else {
528
				return false;
539
				return false;
529
			}
540
			}
530
		final IClasspathEntry[] oldEntries = previousSessionContainer.getClasspathEntries();
541
		final IClasspathEntry[] oldEntries = previousContainer.getClasspathEntries();
531
		if (oldEntries.length != newEntries.length) 
542
		if (oldEntries.length != newEntries.length) 
532
			return false;
543
			return false;
533
		for (int i = 0, length = newEntries.length; i < length; i++) {
544
		for (int i = 0, length = newEntries.length; i < length; i++) {
Lines 594-605 Link Here
594
	}
605
	}
595
	
606
	
596
	private void containerRemoveInitializationInProgress(IJavaProject project, IPath containerPath) {
607
	private void containerRemoveInitializationInProgress(IJavaProject project, IPath containerPath) {
597
		HashSet projectInitializations = containerInitializationInProgress(project);
608
		Map initializations = (Map)this.containerInitializationInProgress.get();
609
		if (initializations == null)
610
			return;
611
		HashSet projectInitializations = (HashSet) initializations.get(project);
612
		if (projectInitializations == null)
613
			return;
598
		projectInitializations.remove(containerPath);
614
		projectInitializations.remove(containerPath);
599
		if (projectInitializations.size() == 0) {
615
		if (projectInitializations.size() == 0)
600
			Map initializations = (Map)this.containerInitializationInProgress.get();
601
			initializations.remove(project);
616
			initializations.remove(project);
602
		}
617
		if (initializations.size() == 0)
618
			this.containerInitializationInProgress.set(null);
603
	}
619
	}
604
	
620
	
605
	private synchronized void containersReset(String[] containerIDs) {
621
	private synchronized void containersReset(String[] containerIDs) {
Lines 1432-1446 Link Here
1432
		}
1448
		}
1433
	}
1449
	}
1434
	
1450
	
1451
	private synchronized boolean batchContainerInitializations() {
1452
		if (this.batchContainerInitializations) {
1453
			this.batchContainerInitializations = false;
1454
			return true;
1455
		}
1456
		return false;
1457
	}
1458
	
1435
	public IClasspathContainer getClasspathContainer(final IPath containerPath, final IJavaProject project) throws JavaModelException {
1459
	public IClasspathContainer getClasspathContainer(final IPath containerPath, final IJavaProject project) throws JavaModelException {
1436
1460
1437
		IClasspathContainer container = containerGet(project, containerPath);
1461
		IClasspathContainer container = containerGet(project, containerPath);
1438
1462
1439
		if (container == null) {
1463
		if (container == null) {
1440
			if (this.batchContainerInitializations) {
1464
			if (batchContainerInitializations()) {
1441
				// avoid deep recursion while initializaing container on workspace restart
1465
				// avoid deep recursion while initializaing container on workspace restart
1442
				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=60437)
1466
				// (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=60437)
1443
				this.batchContainerInitializations = false;
1444
				container = initializeAllContainers(project, containerPath);
1467
				container = initializeAllContainers(project, containerPath);
1445
			} else {
1468
			} else {
1446
				container = initializeContainer(project, containerPath);
1469
				container = initializeContainer(project, containerPath);
Lines 1980-1986 Link Here
1980
			IProject project = projects[i];
2003
			IProject project = projects[i];
1981
			if (!JavaProject.hasJavaNature(project)) continue;
2004
			if (!JavaProject.hasJavaNature(project)) continue;
1982
			IJavaProject javaProject = new JavaProject(project, getJavaModel());
2005
			IJavaProject javaProject = new JavaProject(project, getJavaModel());
1983
			HashSet paths = null;
2006
			HashSet paths = (HashSet) allContainerPaths.get(javaProject);
1984
			IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
2007
			IClasspathEntry[] rawClasspath = javaProject.getRawClasspath();
1985
			for (int j = 0, length2 = rawClasspath.length; j < length2; j++) {
2008
			for (int j = 0, length2 = rawClasspath.length; j < length2; j++) {
1986
				IClasspathEntry entry = rawClasspath[j];
2009
				IClasspathEntry entry = rawClasspath[j];
Lines 1992-1997 Link Here
1992
						allContainerPaths.put(javaProject, paths);
2015
						allContainerPaths.put(javaProject, paths);
1993
					}
2016
					}
1994
					paths.add(path);
2017
					paths.add(path);
2018
					// mark container as being initialized
2019
					containerAddInitializationInProgress(javaProject, path);
1995
				}
2020
				}
1996
			}
2021
			}
1997
			/* TODO (frederic) put back when JDT/UI dummy project will be thrown away...
2022
			/* TODO (frederic) put back when JDT/UI dummy project will be thrown away...
Lines 2013-2023 Link Here
2013
			allContainerPaths.put(javaProjectToInit, containerPaths);
2038
			allContainerPaths.put(javaProjectToInit, containerPaths);
2014
		}
2039
		}
2015
		containerPaths.add(containerToInit);
2040
		containerPaths.add(containerToInit);
2041
		// mark container as being initialized
2042
		containerAddInitializationInProgress(javaProjectToInit, containerToInit);
2016
		// end block
2043
		// end block
2017
		
2044
		
2018
		// mark all containers as being initialized
2019
		this.containerInitializationInProgress.set(allContainerPaths);
2020
		
2021
		// initialize all containers
2045
		// initialize all containers
2022
		boolean ok = false;
2046
		boolean ok = false;
2023
		try {
2047
		try {
Lines 4047-4052 Link Here
4047
		return (IPath)this.variables.get(variableName);
4071
		return (IPath)this.variables.get(variableName);
4048
	}
4072
	}
4049
4073
4074
	private synchronized IPath variableGetDefaultToPreviousSession(String variableName){
4075
		IPath variablePath = (IPath)this.variables.get(variableName);
4076
		if (variablePath == null)
4077
			return getPreviousSessionVariable(variableName);
4078
		return variablePath;
4079
	}
4080
4050
	/*
4081
	/*
4051
	 * Returns the set of variable names that are being initialized in the current thread.
4082
	 * Returns the set of variable names that are being initialized in the current thread.
4052
	 */
4083
	 */
Lines 4110-4115 Link Here
4110
		}
4141
		}
4111
	}
4142
	}
4112
4143
4144
	/*
4145
	 * Optimize startup case where 1 variable is initialized at a time with the same value as on shutdown.
4146
	 */
4147
	public boolean variablePutIfInitializingWithSameValue(String[] variableNames, IPath[] variablePaths) {
4148
		if (variableNames.length != 1)
4149
			return false;
4150
		String variableName = variableNames[0];
4151
		IPath oldPath = variableGetDefaultToPreviousSession(variableName);
4152
		if (oldPath == null)
4153
			return false;
4154
		IPath newPath = variablePaths[0];
4155
		if (!oldPath.equals(newPath))
4156
			return false;
4157
		variablePut(variableName, newPath);
4158
		return true;
4159
	}
4160
4113
	public void contentTypeChanged(ContentTypeChangeEvent event) {
4161
	public void contentTypeChanged(ContentTypeChangeEvent event) {
4114
		Util.resetJavaLikeExtensions();
4162
		Util.resetJavaLikeExtensions();
4115
		
4163
		

Return to bug 175849