Copyright (c) 2000, 2015 IBM Corporation and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which accompanies this distribution, and is available at https://www.eclipse.org/legal/epl-2.0/ SPDX-License-Identifier: EPL-2.0 Contributors: IBM Corporation - initial API and implementation Martin Oberhuber (Wind River) - [245937] setLinkLocation() detects non-change Serge Beauchamp (Freescale Semiconductor) - [229633] Project Path Variable Support Markus Schorn (Wind River) - [306575] Save snapshot location with project Broadcom Corporation - build configurations and references Lars Vogel - Bug 473427
/******************************************************************************* * Copyright (c) 2000, 2015 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * IBM Corporation - initial API and implementation * Martin Oberhuber (Wind River) - [245937] setLinkLocation() detects non-change * Serge Beauchamp (Freescale Semiconductor) - [229633] Project Path Variable Support * Markus Schorn (Wind River) - [306575] Save snapshot location with project * Broadcom Corporation - build configurations and references * Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427 *******************************************************************************/
package org.eclipse.core.internal.resources; import java.net.URI; import java.util.*; import java.util.Map.Entry; import org.eclipse.core.filesystem.URIUtil; import org.eclipse.core.internal.events.BuildCommand; import org.eclipse.core.internal.utils.FileUtil; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; public class ProjectDescription extends ModelObject implements IProjectDescription { // constants private static final IBuildConfiguration[] EMPTY_BUILD_CONFIG_REFERENCE_ARRAY = new IBuildConfiguration[0]; private static final ICommand[] EMPTY_COMMAND_ARRAY = new ICommand[0]; private static final IProject[] EMPTY_PROJECT_ARRAY = new IProject[0]; private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final String EMPTY_STR = ""; //$NON-NLS-1$ protected static boolean isReading = false; //flags to indicate when we are in the middle of reading or writing a // workspace description //these can be static because only one description can be read at once. protected static boolean isWriting = false; protected ICommand[] buildSpec = EMPTY_COMMAND_ARRAY; protected String comment = EMPTY_STR; // Build configuration + References state
Id of the currently active build configuration
/** Id of the currently active build configuration */
protected String activeConfiguration = IBuildConfiguration.DEFAULT_CONFIG_NAME;
The 'real' build configuration names set on this project. This doesn't contain the generated 'default' build configuration with name IBuildConfiguration.DEFAULT_CONFIG_NAME when no build configurations have been defined.
/** * The 'real' build configuration names set on this project. * This doesn't contain the generated 'default' build configuration with name * {@link IBuildConfiguration#DEFAULT_CONFIG_NAME} * when no build configurations have been defined. */
protected String[] configNames = EMPTY_STRING_ARRAY; // Static + Dynamic project level references protected IProject[] staticRefs = EMPTY_PROJECT_ARRAY; protected IProject[] dynamicRefs = EMPTY_PROJECT_ARRAY;
Map from config name in this project -> build configurations in other projects
/** Map from config name in this project -&gt; build configurations in other projects */
protected HashMap<String, IBuildConfiguration[]> dynamicConfigRefs = new HashMap<>(1); // Cache of the build configurations protected volatile IBuildConfiguration[] cachedBuildConfigs; // Cached build configuration references. Not persisted. protected Map<String, IBuildConfiguration[]> cachedConfigRefs = Collections.synchronizedMap(new HashMap<>(1));
Cached project level references. Synchronize on cachedRefsMutex before reading or writing. Increment cachedRefsDirtyCount whenever this is dirtied.
/** * Cached project level references. Synchronize on {@link #cachedRefsMutex} before reading or writing. Increment * {@link #cachedRefsDirtyCount} whenever this is dirtied. */
protected IProject[] cachedRefs;
Counts the number of times cachedRefs has been dirtied. Can be used to determine if dynamic dependencies have changed during an operation that is intended to be atomic with respect to dynamic dependencies. Synchronize on cachedRefsMutex before accessing.
/** * Counts the number of times {@link #cachedRefs} has been dirtied. Can be used to determine if dynamic dependencies have * changed during an operation that is intended to be atomic with respect to dynamic dependencies. Synchronize on * {@link #cachedRefsMutex} before accessing. */
protected int cachedRefsDirtyCount;
Mutex used to protect cachedRefs and cachedRefsDirtyCount.
/** * Mutex used to protect {@link #cachedRefs} and {@link #cachedRefsDirtyCount}. */
protected final Object cachedRefsMutex = new Object();
Map of (IPath -> LinkDescription) pairs for each linked resource in this project, where IPath is the project relative path of the resource.
/** * Map of (IPath -&gt; LinkDescription) pairs for each linked resource * in this project, where IPath is the project relative path of the resource. */
protected HashMap<IPath, LinkDescription> linkDescriptions = null;
Map of (IPath -> LinkedList<FilterDescription>) pairs for each filtered resource in this project, where IPath is the project relative path of the resource.
/** * Map of {@literal (IPath -> LinkedList<FilterDescription>)} pairs for each filtered resource * in this project, where IPath is the project relative path of the resource. */
protected HashMap<IPath, LinkedList<FilterDescription>> filterDescriptions = null;
Map of (String -> VariableDescription) pairs for each variable in this project, where String is the name of the variable.
/** * Map of (String -&gt; VariableDescription) pairs for each variable in this * project, where String is the name of the variable. */
protected HashMap<String, VariableDescription> variableDescriptions = null; // fields protected URI location = null; protected String[] natures = EMPTY_STRING_ARRAY; protected URI snapshotLocation = null; public ProjectDescription() { super(); } @Override @SuppressWarnings({"unchecked"}) public Object clone() { ProjectDescription clone = (ProjectDescription) super.clone(); //don't want the clone to have access to our internal link locations table or builders clone.linkDescriptions = null; clone.filterDescriptions = null; if (variableDescriptions != null) clone.variableDescriptions = (HashMap<String, VariableDescription>) variableDescriptions.clone(); clone.buildSpec = getBuildSpec(true); clone.dynamicConfigRefs = (HashMap<String, IBuildConfiguration[]>) dynamicConfigRefs.clone(); clone.cachedConfigRefs = Collections.synchronizedMap(new HashMap<>(1)); clone.clearCachedDynamicReferences(null); return clone; }
Clear cached references for the specified build config name or all if configName is null.
/** * Clear cached references for the specified build config name * or all if configName is null. */
public void clearCachedDynamicReferences(String configName) { synchronized (cachedRefsMutex) { if (configName == null) cachedConfigRefs.clear(); else cachedConfigRefs.remove(configName); cachedRefs = null; cachedRefsDirtyCount++; } }
Returns a copy of the given array of build configs with all duplicates removed
/** * Returns a copy of the given array of build configs with all duplicates removed */
private IBuildConfiguration[] copyAndRemoveDuplicates(IBuildConfiguration[] values) { Set<IBuildConfiguration> set = new LinkedHashSet<>(Arrays.asList(values)); return set.toArray(new IBuildConfiguration[set.size()]); }
Returns a copy of the given array with all duplicates removed
/** * Returns a copy of the given array with all duplicates removed */
private IProject[] copyAndRemoveDuplicates(IProject[] projects) { IProject[] result = new IProject[projects.length]; int count = 0; next: for (IProject project : projects) { // scan to see if there are any other projects by the same name for (int j = 0; j < count; j++) if (project.equals(result[j])) continue next; // not found result[count++] = project; } if (count < projects.length) { //shrink array IProject[] reduced = new IProject[count]; System.arraycopy(result, 0, reduced, 0, count); return reduced; } return result; }
Helper to turn an array of projects into an array of IBuildConfiguration to the projects' active configuration Order is preserved - the buildConfigs appear for each project in the order that the projects were specified.
Params:
  • projects – projects to get the active configuration from
Returns:collection of build config references
/** * Helper to turn an array of projects into an array of {@link IBuildConfiguration} to the * projects' active configuration * Order is preserved - the buildConfigs appear for each project in the order * that the projects were specified. * @param projects projects to get the active configuration from * @return collection of build config references */
private Collection<BuildConfiguration> getBuildConfigReferencesFromProjects(IProject[] projects) { List<BuildConfiguration> refs = new ArrayList<>(projects.length); for (IProject project : projects) refs.add(new BuildConfiguration(project, null)); return refs; }
Helper to fetch projects from an array of build configuration references
Params:
  • refs –
Returns:List<IProject>
/** * Helper to fetch projects from an array of build configuration references * @param refs * @return {@literal List<IProject>} */
private Collection<IProject> getProjectsFromBuildConfigRefs(IBuildConfiguration[] refs) { LinkedHashSet<IProject> projects = new LinkedHashSet<>(refs.length); for (IBuildConfiguration ref : refs) projects.add(ref.getProject()); return projects; } public String getActiveBuildConfig() { return activeConfiguration; }
Returns the union of the description's static and dynamic project references, with duplicates omitted. The calculation is optimized by caching the result Call the configuration based implementation.
See Also:
  • getAllBuildConfigReferences(IProject, String, boolean)
/** * Returns the union of the description's static and dynamic project references, * with duplicates omitted. The calculation is optimized by caching the result * Call the configuration based implementation. * @see #getAllBuildConfigReferences(IProject, String, boolean) */
public IProject[] getAllReferences(IProject project, boolean makeCopy) { int dirtyCount; IProject[] projRefs; synchronized (cachedRefsMutex) { projRefs = cachedRefs; dirtyCount = cachedRefsDirtyCount; } // Retry this computation until we're able to proceed to the end without someone dirtying the cache. // This loop is here to prevent us from caching a stale result if someone dirties the cache between // the time we invoke getAllBuildConfigReferences and the time we can write to cachedRefs. while (projRefs == null) { IBuildConfiguration[] refs; if (hasBuildConfig(activeConfiguration)) refs = getAllBuildConfigReferences(project, activeConfiguration, false); else if (configNames.length > 0) refs = getAllBuildConfigReferences(project, configNames[0], false); else // No build configuration => fall-back to default refs = getAllBuildConfigReferences(project, IBuildConfiguration.DEFAULT_CONFIG_NAME, false); Collection<IProject> l = getProjectsFromBuildConfigRefs(refs); synchronized (cachedRefsMutex) { // If nobody dirtied the cache since the start of this operation then we can cache the // new result and end the loop. if (cachedRefsDirtyCount == dirtyCount) { cachedRefs = l.toArray(new IProject[l.size()]); } projRefs = cachedRefs; dirtyCount = cachedRefsDirtyCount; } } //still need to copy the result to prevent tampering with the cache return makeCopy ? (IProject[]) projRefs.clone() : projRefs; }
The main entrance point to fetch the full set of Project references. Returns the union of all the description's references. Includes static and dynamic project level references as well as build configuration references for the configuration with the given id. Duplicates are omitted. The calculation is optimized by caching the result. Note that these BuildConfiguration references may have null name. They must be resolved using BuildConfiguration.getBuildConfig() before use. Returns an empty array if the given configName does not exist in the description.
/** * The main entrance point to fetch the full set of Project references. * * Returns the union of all the description's references. Includes static and dynamic * project level references as well as build configuration references for the configuration * with the given id. * Duplicates are omitted. The calculation is optimized by caching the result. * Note that these BuildConfiguration references may have <code>null</code> name. They must * be resolved using {@link BuildConfiguration#getBuildConfig()} before use. * Returns an empty array if the given configName does not exist in the description. */
public IBuildConfiguration[] getAllBuildConfigReferences(IProject project, String configName, boolean makeCopy) { if (!hasBuildConfig(configName)) return EMPTY_BUILD_CONFIG_REFERENCE_ARRAY; IBuildConfiguration[] refs = cachedConfigRefs.get(configName); if (refs == null) { Set<IBuildConfiguration> references = new LinkedHashSet<>(); IBuildConfiguration[] dynamicBuildConfigs = dynamicConfigRefs.containsKey(configName) ? dynamicConfigRefs.get(configName) : EMPTY_BUILD_CONFIG_REFERENCE_ARRAY; Collection<BuildConfiguration> dynamic; try { IBuildConfiguration buildConfig = project.getBuildConfig(configName); dynamic = getBuildConfigReferencesFromProjects(computeDynamicReferencesForProject(buildConfig, getBuildSpec())); } catch (CoreException e) { dynamic = Collections.emptyList(); } Collection<BuildConfiguration> legacyDynamic = getBuildConfigReferencesFromProjects(dynamicRefs); Collection<BuildConfiguration> statik = getBuildConfigReferencesFromProjects(staticRefs); // Combine all references: // New build config references (which only come in dynamic form) trump all others. references.addAll(Arrays.asList(dynamicBuildConfigs)); // We preserve the previous order of static project references before dynamic project references references.addAll(statik); references.addAll(legacyDynamic); references.addAll(dynamic); refs = references.toArray(new IBuildConfiguration[references.size()]); cachedConfigRefs.put(configName, refs); } return makeCopy ? (IBuildConfiguration[]) refs.clone() : refs; }
Used by Project to get the buildConfigs on the description.
Returns:the project configurations
/** * Used by Project to get the buildConfigs on the description. * @return the project configurations */
public IBuildConfiguration[] getBuildConfigs(IProject project, boolean makeCopy) { IBuildConfiguration[] configs = cachedBuildConfigs; // Ensure project is up to date in the cache if (configs != null && !project.equals(configs[0].getProject())) configs = null; if (configs == null) { if (configNames.length == 0) configs = new IBuildConfiguration[] {new BuildConfiguration(project)}; else { configs = new IBuildConfiguration[configNames.length]; for (int i = 0; i < configs.length; i++) configs[i] = new BuildConfiguration(project, configNames[i]); } cachedBuildConfigs = configs; } return makeCopy ? (IBuildConfiguration[]) configs.clone() : configs; } @Override public IBuildConfiguration[] getBuildConfigReferences(String configName) { return getBuildConfigRefs(configName, true); } public IBuildConfiguration[] getBuildConfigRefs(String configName, boolean makeCopy) { if (!hasBuildConfig(configName) || !dynamicConfigRefs.containsKey(configName)) return EMPTY_BUILD_CONFIG_REFERENCE_ARRAY; return makeCopy ? (IBuildConfiguration[]) dynamicConfigRefs.get(configName).clone() : dynamicConfigRefs.get(configName); }
Returns the build configuration references map
Params:
  • makeCopy –
/** * Returns the build configuration references map * @param makeCopy */
@SuppressWarnings({"unchecked"}) public Map<String, IBuildConfiguration[]> getBuildConfigReferences(boolean makeCopy) { return makeCopy ? (Map<String, IBuildConfiguration[]>) dynamicConfigRefs.clone() : dynamicConfigRefs; } @Override public ICommand[] getBuildSpec() { return getBuildSpec(true); } public ICommand[] getBuildSpec(boolean makeCopy) { //thread safety: copy reference in case of concurrent write ICommand[] oldCommands = this.buildSpec; if (oldCommands == null) return EMPTY_COMMAND_ARRAY; if (!makeCopy) return oldCommands; ICommand[] result = new ICommand[oldCommands.length]; for (int i = 0; i < result.length; i++) result[i] = (ICommand) ((BuildCommand) oldCommands[i]).clone(); return result; } @Override public String getComment() { return comment; } @Override public IProject[] getDynamicReferences() { return getDynamicReferences(true); } public IProject[] getDynamicReferences(boolean makeCopy) { return makeCopy ? (IProject[]) dynamicRefs.clone() : dynamicRefs; }
Returns the link location for the given resource name. Returns null if no such link exists.
/** * Returns the link location for the given resource name. Returns null if * no such link exists. */
public URI getLinkLocationURI(IPath aPath) { if (linkDescriptions == null) return null; LinkDescription desc = linkDescriptions.get(aPath); return desc == null ? null : desc.getLocationURI(); }
Returns the filter for the given resource name. Returns null if no such filter exists.
/** * Returns the filter for the given resource name. Returns null if * no such filter exists. */
synchronized public LinkedList<FilterDescription> getFilter(IPath aPath) { if (filterDescriptions == null) return null; return filterDescriptions.get(aPath); }
Returns the map of link descriptions (IPath (project relative path) -> LinkDescription). Since this method is only used internally, it never creates a copy. Returns null if the project does not have any linked resources.
/** * Returns the map of link descriptions (IPath (project relative path) -&gt; LinkDescription). * Since this method is only used internally, it never creates a copy. * Returns null if the project does not have any linked resources. */
public HashMap<IPath, LinkDescription> getLinks() { return linkDescriptions; }
Returns the map of filter descriptions (IPath (project relative path) -> LinkedList<FilterDescription>). Since this method is only used internally, it never creates a copy. Returns null if the project does not have any filtered resources.
/** * Returns the map of filter descriptions (IPath (project relative path) -&gt; * {@literal LinkedList<FilterDescription>}). Since this method is only used * internally, it never creates a copy. Returns null if the project does not * have any filtered resources. */
public HashMap<IPath, LinkedList<FilterDescription>> getFilters() { return filterDescriptions; }
Returns the map of variable descriptions (String (variable name) -> VariableDescription). Since this method is only used internally, it never creates a copy. Returns null if the project does not have any variables.
/** * Returns the map of variable descriptions (String (variable name) -&gt; * VariableDescription). Since this method is only used internally, it never * creates a copy. Returns null if the project does not have any variables. */
public HashMap<String, VariableDescription> getVariables() { return variableDescriptions; }
See Also:
  • getLocation.getLocation()
Deprecated:
/** * @see IProjectDescription#getLocation() * @deprecated */
@Override @Deprecated public IPath getLocation() { if (location == null) return null; return FileUtil.toPath(location); } @Override public URI getLocationURI() { return location; } @Override public String[] getNatureIds() { return getNatureIds(true); } public String[] getNatureIds(boolean makeCopy) { if (natures == null) return EMPTY_STRING_ARRAY; return makeCopy ? (String[]) natures.clone() : natures; } @Override public IProject[] getReferencedProjects() { return getReferencedProjects(true); } public IProject[] getReferencedProjects(boolean makeCopy) { if (staticRefs == null) return EMPTY_PROJECT_ARRAY; return makeCopy ? (IProject[]) staticRefs.clone() : staticRefs; }
Returns the URI to load a resource snapshot from. May return null if no snapshot is set.

EXPERIMENTAL. This constant has been added as part of a work in progress. There is no guarantee that this API will work or that it will remain the same. Please do not use this API without consulting with the Platform Core team.

See Also:
Returns:the snapshot location URI, or null.
Since:3.6
/** * Returns the URI to load a resource snapshot from. * May return <code>null</code> if no snapshot is set. * <p> * <strong>EXPERIMENTAL</strong>. This constant has been added as * part of a work in progress. There is no guarantee that this API will * work or that it will remain the same. Please do not use this API without * consulting with the Platform Core team. * </p> * @return the snapshot location URI, * or <code>null</code>. * @see IProject#loadSnapshot(int, URI, IProgressMonitor) * @see #setSnapshotLocationURI(URI) * @since 3.6 */
public URI getSnapshotLocationURI() { return snapshotLocation; } @Override public boolean hasNature(String natureID) { String[] natureIDs = getNatureIds(false); for (String natureID2 : natureIDs) if (natureID2.equals(natureID)) return true; return false; }
Helper method to compare two maps of Configuration Name -> IBuildConfigurationReference[]
Returns:boolean indicating if there are differences between the two maps
/** * Helper method to compare two maps of Configuration Name -&gt; IBuildConfigurationReference[] * @return boolean indicating if there are differences between the two maps */
private static boolean configRefsHaveChanges(Map<String, IBuildConfiguration[]> m1, Map<String, IBuildConfiguration[]> m2) { if (m1.size() != m2.size()) return true; for (Entry<String, IBuildConfiguration[]> e : m1.entrySet()) { if (!m2.containsKey(e.getKey())) return true; if (!Arrays.equals(e.getValue(), m2.get(e.getKey()))) return true; } return false; }
Internal method to check if the description has a given build configuration.
/** * Internal method to check if the description has a given build configuration. */
boolean hasBuildConfig(String buildConfigName) { Assert.isNotNull(buildConfigName); if (configNames.length == 0) return IBuildConfiguration.DEFAULT_CONFIG_NAME.equals(buildConfigName); for (String configName : configNames) if (configName.equals(buildConfigName)) return true; return false; }
Returns true if any private attributes of the description have changed. Private attributes are those that are not stored in the project description file (.project).
/** * Returns true if any private attributes of the description have changed. * Private attributes are those that are not stored in the project description * file (.project). */
public boolean hasPrivateChanges(ProjectDescription description) { if (location == null) { if (description.location != null) return true; } else if (!location.equals(description.location)) return true; if (!Arrays.equals(dynamicRefs, description.dynamicRefs)) return true; // Build Configuration state if (!activeConfiguration.equals(description.activeConfiguration)) return true; if (!Arrays.equals(configNames, description.configNames)) return true; // Configuration level references if (configRefsHaveChanges(dynamicConfigRefs, description.dynamicConfigRefs)) return true; return false; }
Returns true if any public attributes of the description have changed. Public attributes are those that are stored in the project description file (.project).
/** * Returns true if any public attributes of the description have changed. * Public attributes are those that are stored in the project description * file (.project). */
public boolean hasPublicChanges(ProjectDescription description) { if (!getName().equals(description.getName())) return true; if (!comment.equals(description.getComment())) return true; //don't bother optimizing if the order has changed if (!Arrays.equals(buildSpec, description.getBuildSpec(false))) return true; if (!Arrays.equals(staticRefs, description.getReferencedProjects(false))) return true; if (!Arrays.equals(natures, description.getNatureIds(false))) return true; HashMap<IPath, LinkedList<FilterDescription>> otherFilters = description.getFilters(); if ((filterDescriptions == null) && (otherFilters != null)) return otherFilters != null; if ((filterDescriptions != null) && !filterDescriptions.equals(otherFilters)) return true; HashMap<String, VariableDescription> otherVariables = description.getVariables(); if ((variableDescriptions == null) && (otherVariables != null)) return true; if ((variableDescriptions != null) && !variableDescriptions.equals(otherVariables)) return true; final HashMap<IPath, LinkDescription> otherLinks = description.getLinks(); if (linkDescriptions != otherLinks) { if (linkDescriptions == null || !linkDescriptions.equals(otherLinks)) return true; } final URI otherSnapshotLoc = description.getSnapshotLocationURI(); if (snapshotLocation != otherSnapshotLoc) { if (snapshotLocation == null || !snapshotLocation.equals(otherSnapshotLoc)) return true; } return false; } @Override public ICommand newCommand() { return new BuildCommand(); } @Override public void setActiveBuildConfig(String configName) { Assert.isNotNull(configName); if (!configName.equals(activeConfiguration)) clearCachedDynamicReferences(null); activeConfiguration = configName; } @Override public void setBuildSpec(ICommand[] value) { Assert.isLegal(value != null); //perform a deep copy in case clients perform further changes to the command ICommand[] result = new ICommand[value.length]; for (int i = 0; i < result.length; i++) { result[i] = (ICommand) ((BuildCommand) value[i]).clone(); //copy the reference to any builder instance from the old build spec //to preserve builder states if possible. for (ICommand element : buildSpec) { if (result[i].equals(element)) { ((BuildCommand) result[i]).setBuilders(((BuildCommand) element).getBuilders()); break; } } } buildSpec = result; } @Override public void setComment(String value) { comment = value; } @Deprecated @Override public void setDynamicReferences(IProject[] value) { Assert.isLegal(value != null); dynamicRefs = copyAndRemoveDuplicates(value); clearCachedDynamicReferences(null); } public void setBuildConfigReferences(HashMap<String, IBuildConfiguration[]> refs) { dynamicConfigRefs = new HashMap<>(refs); clearCachedDynamicReferences(null); } @Override public void setBuildConfigReferences(String configName, IBuildConfiguration[] references) { Assert.isLegal(configName != null); Assert.isLegal(references != null); if (!hasBuildConfig(configName)) return; dynamicConfigRefs.put(configName, copyAndRemoveDuplicates(references)); clearCachedDynamicReferences(configName); } @Override public void setBuildConfigs(String[] names) { // Remove references for deleted buildConfigs LinkedHashSet<String> buildConfigNames = new LinkedHashSet<>(); if (names == null || names.length == 0) { configNames = EMPTY_STRING_ARRAY; buildConfigNames.add(IBuildConfiguration.DEFAULT_CONFIG_NAME); } else { // Filter out duplicates for (String n : names) { Assert.isLegal(n != null); buildConfigNames.add(n); } if (buildConfigNames.size() == 1 && ((buildConfigNames.iterator().next())).equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) configNames = EMPTY_STRING_ARRAY; else configNames = buildConfigNames.toArray(new String[buildConfigNames.size()]); } // Remove references for deleted buildConfigs boolean modified = dynamicConfigRefs.keySet().retainAll(buildConfigNames); if (modified) clearCachedDynamicReferences(null); // Clear the cached IBuildConfiguration[] cachedBuildConfigs = null; }
Sets the map of link descriptions (String name -> LinkDescription). Since this method is only used internally, it never creates a copy. May pass null if this project does not have any linked resources
/** * Sets the map of link descriptions (String name -&gt; LinkDescription). * Since this method is only used internally, it never creates a copy. May * pass null if this project does not have any linked resources */
public void setLinkDescriptions(HashMap<IPath, LinkDescription> linkDescriptions) { this.linkDescriptions = linkDescriptions; }
Sets the map of filter descriptions (String name -> LinkedList<LinkDescription>). Since this method is only used internally, it never creates a copy. May pass null if this project does not have any filtered resources
/** * Sets the map of filter descriptions {@literal (String name -> LinkedList<LinkDescription>)}. * Since this method is only used internally, it never creates a copy. May * pass null if this project does not have any filtered resources */
public void setFilterDescriptions(HashMap<IPath, LinkedList<FilterDescription>> filterDescriptions) { this.filterDescriptions = filterDescriptions; }
Sets the map of variable descriptions (String name -> VariableDescription). Since this method is only used internally, it never creates a copy. May pass null if this project does not have any variables
/** * Sets the map of variable descriptions (String name -&gt; * VariableDescription). Since this method is only used internally, it never * creates a copy. May pass null if this project does not have any variables */
public void setVariableDescriptions(HashMap<String, VariableDescription> variableDescriptions) { this.variableDescriptions = variableDescriptions; }
Sets the description of a link. Setting to a description of null will remove the link from the project description.
Returns:true if the description was actually changed, false otherwise.
Since:3.5 returns boolean (was void before)
/** * Sets the description of a link. Setting to a description of null will * remove the link from the project description. * @return <code>true</code> if the description was actually changed, * <code>false</code> otherwise. * @since 3.5 returns boolean (was void before) */
@SuppressWarnings({"unchecked"}) public boolean setLinkLocation(IPath path, LinkDescription description) { HashMap<IPath, LinkDescription> tempMap = linkDescriptions; if (description != null) { //addition or modification if (tempMap == null) tempMap = new HashMap<>(10); else //copy on write to protect against concurrent read tempMap = (HashMap<IPath, LinkDescription>) tempMap.clone(); Object oldValue = tempMap.put(path, description); if (oldValue != null && description.equals(oldValue)) { //not actually changed anything return false; } linkDescriptions = tempMap; } else { //removal if (tempMap == null) return false; //copy on write to protect against concurrent access HashMap<IPath, LinkDescription> newMap = (HashMap<IPath, LinkDescription>) tempMap.clone(); Object oldValue = newMap.remove(path); if (oldValue == null) { //not actually changed anything return false; } linkDescriptions = newMap.isEmpty() ? null : newMap; } return true; }
Add the description of a filter. Setting to a description of null will remove the filter from the project description.
/** * Add the description of a filter. Setting to a description of null will * remove the filter from the project description. */
synchronized public void addFilter(IPath path, FilterDescription description) { Assert.isNotNull(description); if (filterDescriptions == null) filterDescriptions = new HashMap<>(10); LinkedList<FilterDescription> descList = filterDescriptions.get(path); if (descList == null) { descList = new LinkedList<>(); filterDescriptions.put(path, descList); } descList.add(description); }
Add the description of a filter. Setting to a description of null will remove the filter from the project description.
/** * Add the description of a filter. Setting to a description of null will * remove the filter from the project description. */
synchronized public void removeFilter(IPath path, FilterDescription description) { if (filterDescriptions != null) { LinkedList<FilterDescription> descList = filterDescriptions.get(path); if (descList != null) { descList.remove(description); if (descList.isEmpty()) { filterDescriptions.remove(path); if (filterDescriptions.isEmpty()) filterDescriptions = null; } } } }
Sets the description of a variable. Setting to a description of null will remove the variable from the project description.
Returns:true if the description was actually changed, false otherwise.
Since:3.5
/** * Sets the description of a variable. Setting to a description of null will * remove the variable from the project description. * @return <code>true</code> if the description was actually changed, * <code>false</code> otherwise. * @since 3.5 */
@SuppressWarnings({"unchecked"}) public boolean setVariableDescription(String name, VariableDescription description) { HashMap<String, VariableDescription> tempMap = variableDescriptions; if (description != null) { // addition or modification if (tempMap == null) tempMap = new HashMap<>(10); else // copy on write to protect against concurrent read tempMap = (HashMap<String, VariableDescription>) tempMap.clone(); Object oldValue = tempMap.put(name, description); if (oldValue != null && description.equals(oldValue)) { //not actually changed anything return false; } variableDescriptions = tempMap; } else { // removal if (tempMap == null) return false; // copy on write to protect against concurrent access HashMap<String, VariableDescription> newMap = (HashMap<String, VariableDescription>) tempMap.clone(); Object oldValue = newMap.remove(name); if (oldValue == null) { //not actually changed anything return false; } variableDescriptions = newMap.isEmpty() ? null : newMap; } return true; }
set the filters for a given resource. Setting to a description of null will remove the filter from the project description.
Returns:true if the description was actually changed, false otherwise.
/** * set the filters for a given resource. Setting to a description of null will * remove the filter from the project description. * @return <code>true</code> if the description was actually changed, * <code>false</code> otherwise. */
synchronized public boolean setFilters(IPath path, LinkedList<FilterDescription> descriptions) { if (descriptions != null) { // addition if (filterDescriptions == null) filterDescriptions = new HashMap<>(10); Object oldValue = filterDescriptions.put(path, descriptions); if (oldValue != null && descriptions.equals(oldValue)) { //not actually changed anything return false; } } else { // removal if (filterDescriptions == null) return false; Object oldValue = filterDescriptions.remove(path); if (oldValue == null) { //not actually changed anything return false; } if (filterDescriptions.isEmpty()) filterDescriptions = null; } return true; } @Override public void setLocation(IPath path) { this.location = path == null ? null : URIUtil.toURI(path); } @Override public void setLocationURI(URI location) { this.location = location; } @Override public void setName(String value) { super.setName(value); } @Override public void setNatureIds(String[] value) { natures = value.clone(); } @Override public void setReferencedProjects(IProject[] value) { Assert.isLegal(value != null); staticRefs = copyAndRemoveDuplicates(value); clearCachedDynamicReferences(null); }
Sets the location URI for a project snapshot that may be loaded automatically when the project is created in a workspace.

EXPERIMENTAL. This method has been added as part of a work in progress. There is no guarantee that this API will work or that it will remain the same. Please do not use this API without consulting with the Platform Core team.

Params:
  • snapshotLocation – the location URI or null to clear the setting
See Also:
Since:3.6
/** * Sets the location URI for a project snapshot that may be * loaded automatically when the project is created in a workspace. * <p> * <strong>EXPERIMENTAL</strong>. This method has been added as * part of a work in progress. There is no guarantee that this API will * work or that it will remain the same. Please do not use this API without * consulting with the Platform Core team. * </p> * @param snapshotLocation the location URI or * <code>null</code> to clear the setting * @see IProject#loadSnapshot(int, URI, IProgressMonitor) * @see #getSnapshotLocationURI() * @since 3.6 */
public void setSnapshotLocationURI(URI snapshotLocation) { this.snapshotLocation = snapshotLocation; } public URI getGroupLocationURI(IPath projectRelativePath) { return LinkDescription.VIRTUAL_LOCATION; }
Updates the dynamic build configuration and reference state to that of the passed in description. Copies in:
  • Active configuration name
  • Dynamic Project References
  • Build configurations list
  • Build Configuration References
Params:
  • description – Project description to copy dynamic state from
Returns:boolean indicating if anything changed requing re-calculation of WS build order
/** * Updates the dynamic build configuration and reference state to that of the passed in * description. * Copies in: * <ul> * <li>Active configuration name</li> * <li>Dynamic Project References</li> * <li>Build configurations list</li> * <li>Build Configuration References</li> * </ul> * @param description Project description to copy dynamic state from * @return boolean indicating if anything changed requing re-calculation of WS build order */
public boolean updateDynamicState(ProjectDescription description) { boolean changed = false; if (!activeConfiguration.equals(description.activeConfiguration)) { changed = true; activeConfiguration = description.activeConfiguration; } if (!Arrays.equals(dynamicRefs, description.dynamicRefs)) { changed = true; setDynamicReferences(description.dynamicRefs); } if (!Arrays.equals(configNames, description.configNames)) { changed = true; setBuildConfigs(description.configNames); } if (configRefsHaveChanges(dynamicConfigRefs, description.dynamicConfigRefs)) { changed = true; dynamicConfigRefs = new HashMap<>(description.dynamicConfigRefs); } if (changed) clearCachedDynamicReferences(null); return changed; }
Computes the dynamic references for the given project + configuration.
/** * Computes the dynamic references for the given project + configuration. */
private static IProject[] computeDynamicReferencesForProject(IBuildConfiguration buildConfig, ICommand[] buildSpec) { List<IProject> result = new ArrayList<>(); for (ICommand command : buildSpec) { IExtension extension = Platform.getExtensionRegistry().getExtension(ResourcesPlugin.PI_RESOURCES, ResourcesPlugin.PT_BUILDERS, command.getBuilderName()); if (extension == null) { continue; } IConfigurationElement[] configurationElements = extension.getConfigurationElements(); if (configurationElements.length == 0) { continue; } IConfigurationElement element = configurationElements[0]; Object executableExtension; try { IConfigurationElement[] children = element.getChildren("dynamicReference"); //$NON-NLS-1$ if (children.length != 0) { executableExtension = children[0].createExecutableExtension("class"); //$NON-NLS-1$ if (executableExtension instanceof IDynamicReferenceProvider) { IDynamicReferenceProvider provider = (IDynamicReferenceProvider) executableExtension; result.addAll(provider.getDependentProjects(buildConfig)); } } } catch (CoreException e) { String problemElement = element.toString(); ResourcesPlugin.getPlugin().getLog().log(new Status(IStatus.ERROR, ResourcesPlugin.PI_RESOURCES, "Unable to load dynamic reference provider: " + problemElement, e)); //$NON-NLS-1$ } } return result.toArray(new IProject[0]); } }