Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 307587 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/core/internal/resources/NatureManager.java (-43 / +51 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2007 IBM Corporation and others.
2
 * Copyright (c) 2000, 2010 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 25-38 Link Here
25
 */
25
 */
26
public class NatureManager implements ILifecycleListener, IManager {
26
public class NatureManager implements ILifecycleListener, IManager {
27
	//maps String (nature ID) -> descriptor objects
27
	//maps String (nature ID) -> descriptor objects
28
	protected Map descriptors;
28
	private Map descriptors;
29
29
30
	//maps IProject -> String[] of enabled natures for that project
30
	//maps IProject -> String[] of enabled natures for that project
31
	protected Map natureEnablements;
31
	private Map natureEnablements;
32
32
33
	//maps String (builder ID) -> String (nature ID)
33
	//maps String (builder ID) -> String (nature ID)
34
	protected Map buildersToNatures = null;
34
	private Map buildersToNatures = null;
35
	//colour constants used in cycle detection algorithm
35
	//color constants used in cycle detection algorithm
36
	private static final byte WHITE = 0;
36
	private static final byte WHITE = 0;
37
	private static final byte GREY = 1;
37
	private static final byte GREY = 1;
38
	private static final byte BLACK = 2;
38
	private static final byte BLACK = 2;
Lines 43-52 Link Here
43
43
44
	/**
44
	/**
45
	 * Computes the list of natures that are enabled for the given project.
45
	 * Computes the list of natures that are enabled for the given project.
46
	 * Enablement computation is subtlely different from nature set
46
	 * Enablement computation is subtlety different from nature set
47
	 * validation, because it must find and remove all inconsistencies.
47
	 * validation, because it must find and remove all inconsistencies.
48
	 */
48
	 */
49
	protected String[] computeNatureEnablements(Project project) {
49
	private String[] computeNatureEnablements(Project project) {
50
		final ProjectDescription description = project.internalGetDescription();
50
		final ProjectDescription description = project.internalGetDescription();
51
		if (description == null)
51
		if (description == null)
52
			return new String[0];//project deleted concurrently
52
			return new String[0];//project deleted concurrently
Lines 136-142 Link Here
136
	/**
136
	/**
137
	 * Configures the nature with the given ID for the given project.
137
	 * Configures the nature with the given ID for the given project.
138
	 */
138
	 */
139
	protected void configureNature(final Project project, final String natureID, final MultiStatus errors) {
139
	private void configureNature(final Project project, final String natureID, final MultiStatus errors) {
140
		ISafeRunnable code = new ISafeRunnable() {
140
		ISafeRunnable code = new ISafeRunnable() {
141
			public void run() throws Exception {
141
			public void run() throws Exception {
142
				IProjectNature nature = createNature(project, natureID);
142
				IProjectNature nature = createNature(project, natureID);
Lines 240-246 Link Here
240
	/**
240
	/**
241
	 * Deconfigures the nature with the given ID for the given project.
241
	 * Deconfigures the nature with the given ID for the given project.
242
	 */
242
	 */
243
	protected void deconfigureNature(final Project project, final String natureID, final MultiStatus status) {
243
	private void deconfigureNature(final Project project, final String natureID, final MultiStatus status) {
244
		final ProjectInfo info = (ProjectInfo) project.getResourceInfo(false, true);
244
		final ProjectInfo info = (ProjectInfo) project.getResourceInfo(false, true);
245
		IProjectNature existingNature = info.getNature(natureID);
245
		IProjectNature existingNature = info.getNature(natureID);
246
		if (existingNature == null) {
246
		if (existingNature == null) {
Lines 275-281 Link Here
275
	/**
275
	/**
276
	 * Marks all nature descriptors that are involved in cycles
276
	 * Marks all nature descriptors that are involved in cycles
277
	 */
277
	 */
278
	protected void detectCycles() {
278
	private void detectCycles() {
279
		Collection values = descriptors.values();
279
		Collection values = descriptors.values();
280
		ProjectNatureDescriptor[] natures = (ProjectNatureDescriptor[]) values.toArray(new ProjectNatureDescriptor[values.size()]);
280
		ProjectNatureDescriptor[] natures = (ProjectNatureDescriptor[]) values.toArray(new ProjectNatureDescriptor[values.size()]);
281
		for (int i = 0; i < natures.length; i++)
281
		for (int i = 0; i < natures.length; i++)
Lines 286-292 Link Here
286
	/**
286
	/**
287
	 * Returns a status indicating failure to configure natures.
287
	 * Returns a status indicating failure to configure natures.
288
	 */
288
	 */
289
	protected IStatus failure(String reason) {
289
	private IStatus failure(String reason) {
290
		return new ResourceStatus(IResourceStatus.INVALID_NATURE_SET, reason);
290
		return new ResourceStatus(IResourceStatus.INVALID_NATURE_SET, reason);
291
	}
291
	}
292
292
Lines 296-316 Link Here
296
	 */
296
	 */
297
	public String findNatureForBuilder(String builderID) {
297
	public String findNatureForBuilder(String builderID) {
298
		if (buildersToNatures == null) {
298
		if (buildersToNatures == null) {
299
			buildersToNatures = new HashMap(10);
299
			synchronized (this) {
300
			IProjectNatureDescriptor[] descs = getNatureDescriptors();
300
				if (buildersToNatures == null) {
301
			for (int i = 0; i < descs.length; i++) {
301
					buildersToNatures = new HashMap(10);
302
				String natureId = descs[i].getNatureId();
302
					IProjectNatureDescriptor[] descs = getNatureDescriptors();
303
				String[] builders = ((ProjectNatureDescriptor) descs[i]).getBuilderIds();
303
					for (int i = 0; i < descs.length; i++) {
304
				for (int j = 0; j < builders.length; j++) {
304
						String natureId = descs[i].getNatureId();
305
					//FIXME: how to handle multiple natures specifying same builder
305
						String[] builders = ((ProjectNatureDescriptor) descs[i]).getBuilderIds();
306
					buildersToNatures.put(builders[j], natureId);
306
						for (int j = 0; j < builders.length; j++) {
307
							//FIXME: how to handle multiple natures specifying same builder
308
							buildersToNatures.put(builders[j], natureId);
309
						}
310
					}
307
				}
311
				}
308
			}
312
			}
309
		}
313
		}
310
		return (String) buildersToNatures.get(builderID);
314
		return (String) buildersToNatures.get(builderID);
311
	}
315
	}
312
316
313
	protected void flushEnablements(IProject project) {
317
	private synchronized void flushEnablements(IProject project) {
314
		if (natureEnablements != null) {
318
		if (natureEnablements != null) {
315
			natureEnablements.remove(project);
319
			natureEnablements.remove(project);
316
			if (natureEnablements.size() == 0) {
320
			if (natureEnablements.size() == 0) {
Lines 323-329 Link Here
323
	 * Returns the cached array of enabled natures for this project,
327
	 * Returns the cached array of enabled natures for this project,
324
	 * or null if there is nothing in the cache.
328
	 * or null if there is nothing in the cache.
325
	 */
329
	 */
326
	protected String[] getEnabledNatures(Project project) {
330
	protected synchronized String[] getEnabledNatures(Project project) {
327
		String[] enabled;
331
		String[] enabled;
328
		if (natureEnablements != null) {
332
		if (natureEnablements != null) {
329
			enabled = (String[]) natureEnablements.get(project);
333
			enabled = (String[]) natureEnablements.get(project);
Lines 340-346 Link Here
340
	 * dependencies starting at root i.  Returns false otherwise.
344
	 * dependencies starting at root i.  Returns false otherwise.
341
	 * Marks all descriptors that are involved in the cycle as invalid.
345
	 * Marks all descriptors that are involved in the cycle as invalid.
342
	 */
346
	 */
343
	protected boolean hasCycles(ProjectNatureDescriptor desc) {
347
	private boolean hasCycles(ProjectNatureDescriptor desc) {
344
		if (desc.colour == BLACK) {
348
		if (desc.colour == BLACK) {
345
			//this subgraph has already been traversed, so we know the answer
349
			//this subgraph has already been traversed, so we know the answer
346
			return desc.hasCycle;
350
			return desc.hasCycle;
Lines 373-379 Link Here
373
	/**
377
	/**
374
	 * Returns true if the given project has linked resources, and false otherwise.
378
	 * Returns true if the given project has linked resources, and false otherwise.
375
	 */
379
	 */
376
	protected boolean hasLinks(IProject project) {
380
	private boolean hasLinks(IProject project) {
377
		try {
381
		try {
378
			IResource[] children = project.members();
382
			IResource[] children = project.members();
379
			for (int i = 0; i < children.length; i++)
383
			for (int i = 0; i < children.length; i++)
Lines 391-397 Link Here
391
	 * memberships.  Returns the name of one such overlap, or null if
395
	 * memberships.  Returns the name of one such overlap, or null if
392
	 * there is no set overlap.
396
	 * there is no set overlap.
393
	 */
397
	 */
394
	protected String hasSetOverlap(IProjectNatureDescriptor one, IProjectNatureDescriptor two) {
398
	private String hasSetOverlap(IProjectNatureDescriptor one, IProjectNatureDescriptor two) {
395
		if (one == null || two == null) {
399
		if (one == null || two == null) {
396
			return null;
400
			return null;
397
		}
401
		}
Lines 411-417 Link Here
411
	/**
415
	/**
412
	 * Perform depth-first insertion of the given nature ID into the result list.
416
	 * Perform depth-first insertion of the given nature ID into the result list.
413
	 */
417
	 */
414
	protected void insert(ArrayList list, Set seen, String id) {
418
	private void insert(ArrayList list, Set seen, String id) {
415
		if (seen.contains(id))
419
		if (seen.contains(id))
416
			return;
420
			return;
417
		seen.add(id);
421
		seen.add(id);
Lines 443-473 Link Here
443
	 * Only initialize the descriptor cache when we know it is actually needed.
447
	 * Only initialize the descriptor cache when we know it is actually needed.
444
	 * Running programs may never need to refer to this cache.
448
	 * Running programs may never need to refer to this cache.
445
	 */
449
	 */
446
	protected void lazyInitialize() {
450
	private void lazyInitialize() {
447
		if (descriptors != null)
451
		if (descriptors != null)
448
			return;
452
			return;
449
		IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_NATURES);
453
		synchronized (this) {
450
		IExtension[] extensions = point.getExtensions();
454
			if (descriptors != null)
451
		descriptors = new HashMap(extensions.length * 2 + 1);
455
				return;
452
		for (int i = 0, imax = extensions.length; i < imax; i++) {
456
			IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_NATURES);
453
			IProjectNatureDescriptor desc = null;
457
			IExtension[] extensions = point.getExtensions();
454
			try {
458
			descriptors = new HashMap(extensions.length * 2 + 1);
455
				desc = new ProjectNatureDescriptor(extensions[i]);
459
			for (int i = 0, imax = extensions.length; i < imax; i++) {
456
			} catch (CoreException e) {
460
				IProjectNatureDescriptor desc = null;
457
				Policy.log(e.getStatus());
461
				try {
462
					desc = new ProjectNatureDescriptor(extensions[i]);
463
				} catch (CoreException e) {
464
					Policy.log(e.getStatus());
465
				}
466
				if (desc != null)
467
					descriptors.put(desc.getNatureId(), desc);
458
			}
468
			}
459
			if (desc != null)
469
			//do cycle detection now so it only has to be done once
460
				descriptors.put(desc.getNatureId(), desc);
470
			//cycle detection on a graph subset is a pain
471
			detectCycles();
461
		}
472
		}
462
		//do cycle detection now so it only has to be done once
463
		//cycle detection on a graph subset is a pain
464
		detectCycles();
465
	}
473
	}
466
474
467
	/**
475
	/**
468
	 * Sets the cached array of enabled natures for this project.
476
	 * Sets the cached array of enabled natures for this project.
469
	 */
477
	 */
470
	protected void setEnabledNatures(IProject project, String[] enablements) {
478
	private void setEnabledNatures(IProject project, String[] enablements) {
471
		if (natureEnablements == null)
479
		if (natureEnablements == null)
472
			natureEnablements = Collections.synchronizedMap(new HashMap(20));
480
			natureEnablements = Collections.synchronizedMap(new HashMap(20));
473
		natureEnablements.put(project, enablements);
481
		natureEnablements.put(project, enablements);
Lines 513-519 Link Here
513
	 * @return An OK status if all additions are valid, and an error status 
521
	 * @return An OK status if all additions are valid, and an error status 
514
	 * 	if any of the additions introduce new inconsistencies.
522
	 * 	if any of the additions introduce new inconsistencies.
515
	 */
523
	 */
516
	protected IStatus validateAdditions(HashSet newNatures, HashSet additions, IProject project) {
524
	private IStatus validateAdditions(HashSet newNatures, HashSet additions, IProject project) {
517
		Boolean hasLinks = null;//three states: true, false, null (not yet computed)
525
		Boolean hasLinks = null;//three states: true, false, null (not yet computed)
518
		//perform checks in order from least expensive to most expensive
526
		//perform checks in order from least expensive to most expensive
519
		for (Iterator added = additions.iterator(); added.hasNext();) {
527
		for (Iterator added = additions.iterator(); added.hasNext();) {
Lines 585-591 Link Here
585
	 * @return An OK status if all removals are valid, and a not OK status 
593
	 * @return An OK status if all removals are valid, and a not OK status 
586
	 * 	if any of the deletions introduce new inconsistencies.
594
	 * 	if any of the deletions introduce new inconsistencies.
587
	 */
595
	 */
588
	protected IStatus validateRemovals(HashSet newNatures, HashSet deletions) {
596
	private IStatus validateRemovals(HashSet newNatures, HashSet deletions) {
589
		//iterate over new nature set, and ensure that none of their prerequisites are being deleted
597
		//iterate over new nature set, and ensure that none of their prerequisites are being deleted
590
		for (Iterator it = newNatures.iterator(); it.hasNext();) {
598
		for (Iterator it = newNatures.iterator(); it.hasNext();) {
591
			String currentID = (String) it.next();
599
			String currentID = (String) it.next();

Return to bug 307587