1 /******************************************************************************* 2 * Copyright (c) 2000, 2015 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * James Blackburn (Broadcom Corp.) - ongoing development 14 * Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427 15 *******************************************************************************/ 16 package org.eclipse.core.internal.resources; 17 18 import java.util.HashMap; 19 import org.eclipse.core.internal.events.BuildCommand; 20 import org.eclipse.core.resources.ICommand; 21 import org.eclipse.core.resources.IProjectNature; 22 import org.eclipse.core.runtime.content.IContentTypeMatcher; 23 24 public class ProjectInfo extends ResourceInfo { 25 26 /** The description of this object */ 27 protected ProjectDescription description; 28 29 /** The list of natures for this project */ 30 protected HashMap<String, IProjectNature> natures; 31 32 /** The property store for this resource (used only by the compatibility fragment) */ 33 protected Object propertyStore; 34 35 /** The content type matcher for this project. */ 36 protected IContentTypeMatcher matcher; 37 38 /** 39 * Discards stale natures on this project after project description 40 * has changed. 41 */ discardNatures()42 public synchronized void discardNatures() { 43 natures = null; 44 } 45 46 /** 47 * Default constructor (for easier debugging) 48 */ ProjectInfo()49 public ProjectInfo() { 50 super(); 51 } 52 53 /** 54 * Discards any stale state on this project after it has been moved. Builder 55 * instances must be cleared because they reference the old project handle. 56 */ fixupAfterMove()57 public synchronized void fixupAfterMove() { 58 natures = null; 59 // note that the property store instance will be recreated lazily 60 propertyStore = null; 61 if (description != null) { 62 ICommand[] buildSpec = description.getBuildSpec(false); 63 for (ICommand element : buildSpec) 64 ((BuildCommand) element).setBuilders(null); 65 } 66 } 67 68 /** 69 * Returns the description associated with this info. The return value may be null. 70 */ getDescription()71 public ProjectDescription getDescription() { 72 return description; 73 } 74 75 /** 76 * Returns the content type matcher associated with this info. The return value may be null. 77 */ getMatcher()78 public IContentTypeMatcher getMatcher() { 79 return matcher; 80 } 81 getNature(String natureId)82 public IProjectNature getNature(String natureId) { 83 // thread safety: (Concurrency001) 84 HashMap<String, IProjectNature> temp = natures; 85 if (temp == null) 86 return null; 87 return temp.get(natureId); 88 } 89 90 /** 91 * Returns the property store associated with this info. The return value may be null. 92 */ 93 @Override getPropertyStore()94 public Object getPropertyStore() { 95 return propertyStore; 96 } 97 98 /** 99 * Sets the description associated with this info. The value may be null. 100 */ setDescription(ProjectDescription value)101 public void setDescription(ProjectDescription value) { 102 if (description != null) { 103 //if we already have a description, assign the new 104 //build spec on top of the old one to ensure we maintain 105 //any existing builder instances in the old build commands 106 ICommand[] oldSpec = description.buildSpec; 107 ICommand[] newSpec = value.buildSpec; 108 value.buildSpec = oldSpec; 109 value.setBuildSpec(newSpec); 110 } 111 description = value; 112 } 113 114 /** 115 * Sets the content type matcher to be associated with this info. The value may be null. 116 */ setMatcher(IContentTypeMatcher matcher)117 public void setMatcher(IContentTypeMatcher matcher) { 118 this.matcher = matcher; 119 } 120 121 @SuppressWarnings({"unchecked"}) setNature(String natureId, IProjectNature value)122 public synchronized void setNature(String natureId, IProjectNature value) { 123 // thread safety: (Concurrency001) 124 if (value == null) { 125 if (natures == null) 126 return; 127 HashMap<String, IProjectNature> temp = (HashMap<String, IProjectNature>) natures.clone(); 128 temp.remove(natureId); 129 if (temp.isEmpty()) 130 natures = null; 131 else 132 natures = temp; 133 } else { 134 HashMap<String, IProjectNature> temp = natures; 135 if (temp == null) 136 temp = new HashMap<>(5); 137 else 138 temp = (HashMap<String, IProjectNature>) natures.clone(); 139 temp.put(natureId, value); 140 natures = temp; 141 } 142 } 143 144 /** 145 * Sets the property store associated with this info. The value may be null. 146 */ 147 @Override setPropertyStore(Object value)148 public void setPropertyStore(Object value) { 149 propertyStore = value; 150 } 151 } 152