mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-05 15:25:49 +02:00
Bug 311189 settings are changed & lost after project set import replaces existing project
This commit is contained in:
parent
a85f49062c
commit
800ab8b171
5 changed files with 270 additions and 212 deletions
|
@ -59,6 +59,7 @@ public class AllCoreTests {
|
||||||
suite.addTest(ASTCacheTests.suite());
|
suite.addTest(ASTCacheTests.suite());
|
||||||
suite.addTest(AsmModelBuilderTest.suite());
|
suite.addTest(AsmModelBuilderTest.suite());
|
||||||
suite.addTest(CModelBuilderBugsTest.suite());
|
suite.addTest(CModelBuilderBugsTest.suite());
|
||||||
|
suite.addTest(Bug311189.suite());
|
||||||
return suite;
|
return suite;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2010 Broadcom Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* James Blackburn (Broadcom Corp) - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.model.tests;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CoreModel;
|
||||||
|
import org.eclipse.cdt.core.model.IPathEntry;
|
||||||
|
import org.eclipse.cdt.core.resources.IPathEntryStore;
|
||||||
|
import org.eclipse.cdt.core.testplugin.ResourceHelper;
|
||||||
|
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||||
|
import org.eclipse.cdt.internal.core.model.SourceEntry;
|
||||||
|
import org.eclipse.core.resources.IFolder;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IWorkspaceRunnable;
|
||||||
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IProgressMonitor;
|
||||||
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regression test for Bug 311189.
|
||||||
|
* When a Team Project Set is imported, replacing an existing CDT Project
|
||||||
|
* we must ensure that we don't corrupt the set of includes in the incoming
|
||||||
|
* project's metadata
|
||||||
|
*/
|
||||||
|
public class Bug311189 extends BaseTestCase {
|
||||||
|
|
||||||
|
public static Test suite() {
|
||||||
|
return suite(Bug311189.class, "_");
|
||||||
|
}
|
||||||
|
|
||||||
|
private IProject project;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
project = ResourceHelper.createCDTProjectWithConfig("bug311189");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a source folder is deleted and re-created in a separate Job, ensure that we don't
|
||||||
|
* delete the source folder from the C Model.
|
||||||
|
*/
|
||||||
|
public void testPathSettingLost() throws Exception {
|
||||||
|
IFolder srcFolder = project.getFolder("src");
|
||||||
|
final IPathEntry sourceEntry = new SourceEntry(srcFolder.getFullPath(), new IPath[0]);
|
||||||
|
|
||||||
|
// create a source folder and set it as a source entry
|
||||||
|
srcFolder.create(true, false, null);
|
||||||
|
CoreModel.setRawPathEntries(CoreModel.getDefault().create(project), new IPathEntry[] {sourceEntry}, null);
|
||||||
|
IPathEntry[] rawEntries = CoreModel.getPathEntryStore(project).getRawPathEntries();
|
||||||
|
assertTrue ("Path entry unset!", Arrays.asList(rawEntries).contains(sourceEntry));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// None-batched resource change, though we do hold a scheduling rule
|
||||||
|
// on the full project. While team operations are batched, doing this
|
||||||
|
// is
|
||||||
|
Job.getJobManager().beginRule(project, null);
|
||||||
|
// Delete the source folder, and re-recreate it
|
||||||
|
srcFolder.delete(true, null);
|
||||||
|
srcFolder.create(true, false, null);
|
||||||
|
} finally {
|
||||||
|
Job.getJobManager().endRule(project);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path entry update should now be running...
|
||||||
|
// Tick a workspace job through the workspace so we get when it's finished
|
||||||
|
ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||||
|
public void run(IProgressMonitor monitor) throws CoreException {
|
||||||
|
}
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
IPathEntryStore store = CoreModel.getPathEntryStore(project);
|
||||||
|
rawEntries = store.getRawPathEntries();
|
||||||
|
assertTrue ("Path entry gone!", Arrays.asList(rawEntries).contains(sourceEntry));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -29,12 +29,29 @@ import org.eclipse.core.runtime.IPath;
|
||||||
|
|
||||||
public abstract class ResourceChangeHandlerBase implements IResourceChangeListener {
|
public abstract class ResourceChangeHandlerBase implements IResourceChangeListener {
|
||||||
public interface IResourceMoveHandler {
|
public interface IResourceMoveHandler {
|
||||||
|
/**
|
||||||
|
* Resource moved fromRc to toRc
|
||||||
|
* @param fromRc
|
||||||
|
* @param toRc
|
||||||
|
* @return boolean indicating if children should be visited
|
||||||
|
*/
|
||||||
boolean handleResourceMove(IResource fromRc, IResource toRc);
|
boolean handleResourceMove(IResource fromRc, IResource toRc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a resource remove
|
||||||
|
* @param rc Removed IResource
|
||||||
|
* @return boolean indicating if children should be visited
|
||||||
|
*/
|
||||||
boolean handleResourceRemove(IResource rc);
|
boolean handleResourceRemove(IResource rc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle a project close
|
||||||
|
*/
|
||||||
void handleProjectClose(IProject project);
|
void handleProjectClose(IProject project);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call-back ticked at end of a resource change event
|
||||||
|
*/
|
||||||
void done();
|
void done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* IBM Corporation
|
* IBM Corporation
|
||||||
|
* James Blackburn (Broadcom Corporation)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.model;
|
package org.eclipse.cdt.internal.core.model;
|
||||||
|
|
||||||
|
@ -61,7 +62,6 @@ import org.eclipse.cdt.internal.core.settings.model.ConfigBasedPathEntryStore;
|
||||||
import org.eclipse.core.resources.IMarker;
|
import org.eclipse.core.resources.IMarker;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.IWorkspaceRunnable;
|
|
||||||
import org.eclipse.core.resources.WorkspaceJob;
|
import org.eclipse.core.resources.WorkspaceJob;
|
||||||
import org.eclipse.core.runtime.CoreException;
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.core.runtime.IConfigurationElement;
|
import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
|
@ -1430,7 +1430,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
|
||||||
* @param sourceRoot
|
* @param sourceRoot
|
||||||
* @throws CModelException
|
* @throws CModelException
|
||||||
*/
|
*/
|
||||||
void updatePathEntryFromDeleteSource(ISourceRoot sourceRoot) throws CModelException {
|
void updatePathEntryFromDeleteSource(final ISourceRoot sourceRoot) throws CModelException {
|
||||||
final ICProject cproject = sourceRoot.getCProject();
|
final ICProject cproject = sourceRoot.getCProject();
|
||||||
IPathEntry[] rawEntries = getRawPathEntries(cproject);
|
IPathEntry[] rawEntries = getRawPathEntries(cproject);
|
||||||
boolean change = false;
|
boolean change = false;
|
||||||
|
@ -1450,29 +1450,12 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
|
||||||
IPathEntry[] newEntries = new IPathEntry[list.size()];
|
IPathEntry[] newEntries = new IPathEntry[list.size()];
|
||||||
list.toArray(newEntries);
|
list.toArray(newEntries);
|
||||||
final IPathEntry[] finalEntries = newEntries;
|
final IPathEntry[] finalEntries = newEntries;
|
||||||
Job updatePathEntry = new Job("PathEntry Update source roots") { //$NON-NLS-1$
|
Job updatePathEntry = new WorkspaceJob("PathEntry Update source roots") { //$NON-NLS-1$
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.IProgressMonitor)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
protected IStatus run(IProgressMonitor monitor) {
|
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
|
||||||
try {
|
// If the path which triggered this change exists when we run this job then nothing to do
|
||||||
CCorePlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
if (sourceRoot.getResource() == null || !sourceRoot.getResource().exists())
|
||||||
|
setRawPathEntries(cproject, finalEntries, monitor);
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor)
|
|
||||||
*/
|
|
||||||
public void run(IProgressMonitor mon) throws CoreException {
|
|
||||||
setRawPathEntries(cproject, finalEntries, mon);
|
|
||||||
}
|
|
||||||
}, null);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
return e.getStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Status.OK_STATUS;
|
return Status.OK_STATUS;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,22 +7,22 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Intel Corporation - Initial API and implementation
|
* Intel Corporation - Initial API and implementation
|
||||||
|
* Broadcom Corporation - Bug 311189 and clean-up
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.settings.model;
|
package org.eclipse.cdt.internal.core.settings.model;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
|
||||||
import org.eclipse.cdt.core.settings.model.ICExclusionPatternPathEntry;
|
|
||||||
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
||||||
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
|
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionManager;
|
||||||
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
|
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
|
||||||
|
@ -30,6 +30,7 @@ import org.eclipse.cdt.core.settings.model.ICSourceEntry;
|
||||||
import org.eclipse.cdt.core.settings.model.WriteAccessException;
|
import org.eclipse.cdt.core.settings.model.WriteAccessException;
|
||||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||||
import org.eclipse.cdt.core.settings.model.util.ResourceChangeHandlerBase;
|
import org.eclipse.cdt.core.settings.model.util.ResourceChangeHandlerBase;
|
||||||
|
import org.eclipse.core.resources.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
import org.eclipse.core.resources.IProject;
|
||||||
import org.eclipse.core.resources.IResource;
|
import org.eclipse.core.resources.IResource;
|
||||||
import org.eclipse.core.resources.IResourceChangeEvent;
|
import org.eclipse.core.resources.IResourceChangeEvent;
|
||||||
|
@ -47,33 +48,76 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
* and associated project storage metadata files, as well as changes to
|
* and associated project storage metadata files, as well as changes to
|
||||||
* source folders
|
* source folders
|
||||||
*
|
*
|
||||||
*
|
* Notifies CProjectDescriptionManager on some events, in particular project close and remove
|
||||||
* delegates parts of it's functionality to CProjectDescriptio
|
|
||||||
*/
|
*/
|
||||||
public class ResourceChangeHandler extends ResourceChangeHandlerBase implements ISaveParticipant {
|
public class ResourceChangeHandler extends ResourceChangeHandlerBase implements ISaveParticipant {
|
||||||
CProjectDescriptionManager fMngr = CProjectDescriptionManager.getInstance();
|
|
||||||
|
|
||||||
class RcMoveHandler implements IResourceMoveHandler {
|
/**
|
||||||
|
* A resource move handler which updates the model when C model resources are moved / removed.
|
||||||
|
* It's responsible for:
|
||||||
|
* - Handling project description update after a project move
|
||||||
|
* - Noticing the removal of directories that correspond to SourceEntrys
|
||||||
|
* - Removing resource specific configuration from removed removed files and folders
|
||||||
|
*
|
||||||
|
* It records changes made during an IResourceChangeEvent for subsequent update to the model. This
|
||||||
|
* is performed in a WorkspaceJob to ensure we don't remove model entries while many changes are in
|
||||||
|
* progress as part of a team operation. See also Bug 311189
|
||||||
|
*/
|
||||||
|
private static class RcMoveHandler implements IResourceMoveHandler {
|
||||||
|
CProjectDescriptionManager fMngr = CProjectDescriptionManager.getInstance();
|
||||||
|
|
||||||
|
/** Map of modified project descriptions to update */
|
||||||
Map<IProject, ICProjectDescription> fProjDesMap = new HashMap<IProject, ICProjectDescription>();
|
Map<IProject, ICProjectDescription> fProjDesMap = new HashMap<IProject, ICProjectDescription>();
|
||||||
Set<IProject> fRemovedProjSet = new HashSet<IProject>();
|
/** Set of removed resources */
|
||||||
|
Collection<IProject> fRemovedProjects = new HashSet<IProject>();
|
||||||
|
/** Map of moved & removed resources: 'from' -> 'to'; 'to' may be null for removed resources */
|
||||||
|
Map<IResource, IResource> fMovedResources = new HashMap<IResource, IResource>();
|
||||||
|
|
||||||
public void handleProjectClose(IProject project) {
|
public void handleProjectClose(IProject project) {
|
||||||
fMngr.projectClosedRemove(project);
|
fMngr.projectClosedRemove(project);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICExclusionPatternPathEntry[] checkMove(IPath fromFullPath, IPath toFullPath, ICExclusionPatternPathEntry[] entries){
|
/**
|
||||||
|
* Check and return a new ICSourceEntry[] when a path has been changed in a project
|
||||||
|
* @param fromFullPath
|
||||||
|
* @param toFullPath
|
||||||
|
* @param entries - source entries to check
|
||||||
|
* @return ICSourceEntry[] or null if no change to the source entries
|
||||||
|
*/
|
||||||
|
private ICSourceEntry[] checkMove(IPath fromFullPath, IPath toFullPath, ICSourceEntry[] entries){
|
||||||
boolean modified = false;
|
boolean modified = false;
|
||||||
for(int k = 0; k < entries.length; k++){
|
for(int k = 0; k < entries.length; k++){
|
||||||
if(entries[k].getFullPath().equals(fromFullPath)){
|
if(entries[k].getFullPath().equals(fromFullPath)){
|
||||||
ICExclusionPatternPathEntry entry = entries[k];
|
ICSourceEntry entry = entries[k];
|
||||||
entries[k] = (ICExclusionPatternPathEntry)CDataUtil.createEntry(entry.getKind(), toFullPath.toString(), null, entry.getExclusionPatterns(), entry.getFlags());
|
entries[k] = (ICSourceEntry)CDataUtil.createEntry(entry.getKind(), toFullPath.toString(), null, entry.getExclusionPatterns(), entry.getFlags());
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return modified ? entries : null;
|
return modified ? entries : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("fallthrough")
|
/**
|
||||||
|
* Check and return a new ICSourceEntry[] which doesn't contain rcFullPath as a source path
|
||||||
|
* @param rcFullPath - that path being removed
|
||||||
|
* @param entries - source entries to check
|
||||||
|
* @return ICSourceEntry[] or null if no change
|
||||||
|
*/
|
||||||
|
private ICSourceEntry[] checkRemove(IPath rcFullPath, ICSourceEntry[] entries) {
|
||||||
|
List<ICSourceEntry> updatedList = null;
|
||||||
|
int num = 0;
|
||||||
|
for (ICSourceEntry entrie : entries) {
|
||||||
|
if(entrie.getFullPath().equals(rcFullPath)){
|
||||||
|
if(updatedList == null){
|
||||||
|
updatedList = new ArrayList<ICSourceEntry>(Arrays.asList(entries));
|
||||||
|
}
|
||||||
|
updatedList.remove(num);
|
||||||
|
} else {
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return updatedList != null ? updatedList.toArray(new ICSourceEntry[updatedList.size()]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean handleResourceMove(IResource fromRc, IResource toRc) {
|
public boolean handleResourceMove(IResource fromRc, IResource toRc) {
|
||||||
boolean proceed = true;
|
boolean proceed = true;
|
||||||
IProject fromProject = fromRc.getProject();
|
IProject fromProject = fromRc.getProject();
|
||||||
|
@ -81,83 +125,32 @@ public class ResourceChangeHandler extends ResourceChangeHandlerBase implements
|
||||||
switch(toRc.getType()){
|
switch(toRc.getType()){
|
||||||
case IResource.PROJECT:{
|
case IResource.PROJECT:{
|
||||||
ICProjectDescription des = fMngr.projectMove(fromProject, toProject);
|
ICProjectDescription des = fMngr.projectMove(fromProject, toProject);
|
||||||
fRemovedProjSet.add(fromProject);
|
fRemovedProjects.add(fromProject);
|
||||||
if(des != null)
|
if(des != null)
|
||||||
fProjDesMap.put(toProject, des);
|
fProjDesMap.put(toProject, des);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IResource.FOLDER:{
|
case IResource.FOLDER:
|
||||||
IPath fromFullPath = fromRc.getFullPath();
|
case IResource.FILE:
|
||||||
IPath toFullPath = toRc.getFullPath();
|
// Only handle move in the same project
|
||||||
if(toFullPath.equals(fromFullPath))
|
// TODO: should we treat this as a remove?
|
||||||
|
if (!toProject.equals(fromProject))
|
||||||
break;
|
break;
|
||||||
|
// If path hasn't changed, nothing to do
|
||||||
if(!toProject.equals(fromProject))
|
if (fromRc.getFullPath().equals(toRc.getFullPath()))
|
||||||
break;
|
break;
|
||||||
|
fMovedResources.put(fromRc, toRc);
|
||||||
ICProjectDescription des = getProjectDescription(toProject, true);
|
|
||||||
if(des != null){
|
|
||||||
ICConfigurationDescription cfgDess[] = des.getConfigurations();
|
|
||||||
for (ICConfigurationDescription cfg : cfgDess) {
|
|
||||||
ICExclusionPatternPathEntry entries[] = cfg.getSourceEntries();
|
|
||||||
entries = checkMove(fromFullPath, toFullPath, entries);
|
|
||||||
if(entries != null){
|
|
||||||
try {
|
|
||||||
cfg.setSourceEntries((ICSourceEntry[])entries);
|
|
||||||
} catch (WriteAccessException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//don't do anything about output entries ICBuildSetting bs = cfg.getBuildSetting();
|
|
||||||
// if(bs != null){
|
|
||||||
// entries = bs.getOutputDirectories();
|
|
||||||
// entries = checkMove(fromFullPath, toFullPath, entries);
|
|
||||||
// if(entries != null){
|
|
||||||
// bs.setOutputDirectories((ICOutputEntry[])entries);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//do not break.. proceed with rc description move
|
|
||||||
}
|
|
||||||
case IResource.FILE:{
|
|
||||||
IPath fromRcProjPath = fromRc.getProjectRelativePath();
|
|
||||||
IPath toRcProjPath = toRc.getProjectRelativePath();
|
|
||||||
if(toRcProjPath.equals(fromRcProjPath))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!toProject.equals(fromProject))
|
|
||||||
break;
|
|
||||||
|
|
||||||
ICProjectDescription des = getProjectDescription(toProject, true);
|
|
||||||
if(des != null){
|
|
||||||
ICConfigurationDescription cfgDess[] = des.getConfigurations();
|
|
||||||
for (ICConfigurationDescription cfgDes : cfgDess) {
|
|
||||||
ICResourceDescription rcDescription = cfgDes.getResourceDescription(fromRcProjPath, true);
|
|
||||||
if(rcDescription != null){
|
|
||||||
try {
|
|
||||||
rcDescription.setPath(toRcProjPath);
|
|
||||||
} catch (WriteAccessException e) {
|
|
||||||
// } catch (CoreException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return proceed;
|
return proceed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICProjectDescription getProjectDescription(IResource rc, boolean load){
|
private ICProjectDescription getProjectDescription(IResource rc) {
|
||||||
IProject project = rc.getProject();
|
IProject project = rc.getProject();
|
||||||
ICProjectDescription des = fProjDesMap.get(project);
|
ICProjectDescription des = fProjDesMap.get(project);
|
||||||
if(des == null && !fProjDesMap.containsKey(project)){
|
if(des == null && !fProjDesMap.containsKey(project)){
|
||||||
int flags = load ? 0 : ICProjectDescriptionManager.GET_IF_LOADDED;
|
int flags = 0;
|
||||||
flags |= CProjectDescriptionManager.INTERNAL_GET_IGNORE_CLOSE;
|
flags |= CProjectDescriptionManager.INTERNAL_GET_IGNORE_CLOSE;
|
||||||
flags |= ICProjectDescriptionManager.GET_WRITABLE;
|
flags |= ICProjectDescriptionManager.GET_WRITABLE;
|
||||||
des = fMngr.getProjectDescription(project, flags);
|
des = fMngr.getProjectDescription(project, flags);
|
||||||
|
@ -167,88 +160,19 @@ public class ResourceChangeHandler extends ResourceChangeHandlerBase implements
|
||||||
return des;
|
return des;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void setProjectDescription(IProject project, ICProjectDescription des){
|
|
||||||
// fProjDesMap.put(project, des);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private List<ICExclusionPatternPathEntry> checkRemove(IPath rcFullPath, ICExclusionPatternPathEntry[] entries){
|
|
||||||
List<ICExclusionPatternPathEntry> updatedList = null;
|
|
||||||
int num = 0;
|
|
||||||
for (ICExclusionPatternPathEntry entrie : entries) {
|
|
||||||
if(entrie.getFullPath().equals(rcFullPath)){
|
|
||||||
if(updatedList == null){
|
|
||||||
updatedList = new ArrayList<ICExclusionPatternPathEntry>(Arrays.asList(entries));
|
|
||||||
}
|
|
||||||
updatedList.remove(num);
|
|
||||||
} else {
|
|
||||||
num++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return updatedList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("fallthrough")
|
|
||||||
public boolean handleResourceRemove(IResource rc) {
|
public boolean handleResourceRemove(IResource rc) {
|
||||||
boolean proceed = true;
|
boolean proceed = true;
|
||||||
IProject project = rc.getProject();
|
IProject project = rc.getProject();
|
||||||
switch(rc.getType()){
|
switch(rc.getType()){
|
||||||
case IResource.PROJECT:
|
case IResource.PROJECT:
|
||||||
fMngr.projectClosedRemove(project);
|
fMngr.projectClosedRemove(project);
|
||||||
fRemovedProjSet.add(project);
|
fRemovedProjects.add(project);
|
||||||
proceed = false;
|
proceed = false;
|
||||||
break;
|
break;
|
||||||
case IResource.FOLDER:
|
case IResource.FOLDER:
|
||||||
if(project.exists()){
|
|
||||||
ICProjectDescription des = getProjectDescription(project, true);
|
|
||||||
if(des != null){
|
|
||||||
IPath rcFullPath = rc.getFullPath();
|
|
||||||
ICConfigurationDescription cfgDess[] = des.getConfigurations();
|
|
||||||
for (ICConfigurationDescription cfg : cfgDess) {
|
|
||||||
ICExclusionPatternPathEntry[] entries = cfg.getSourceEntries();
|
|
||||||
List<ICExclusionPatternPathEntry> updatedList = checkRemove(rcFullPath, entries);
|
|
||||||
|
|
||||||
if(updatedList != null){
|
|
||||||
try {
|
|
||||||
cfg.setSourceEntries(updatedList.toArray(new ICSourceEntry[updatedList.size()]));
|
|
||||||
} catch (WriteAccessException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//don't do anything about output entries ICBuildSetting bs = cfg.getBuildSetting();
|
|
||||||
// if(bs != null){
|
|
||||||
// entries = bs.getOutputDirectories();
|
|
||||||
// updatedList = checkRemove(rcFullPath, entries);
|
|
||||||
// if(updatedList != null){
|
|
||||||
// bs.setOutputDirectories((ICOutputEntry[])updatedList.toArray(new ICOutputEntry[updatedList.size()]));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//do not break.. proceed with rc description remove
|
|
||||||
case IResource.FILE:
|
case IResource.FILE:
|
||||||
if(project.exists()){
|
if (project.isAccessible())
|
||||||
ICProjectDescription des = getProjectDescription(project, true);
|
fMovedResources.put(rc, null);
|
||||||
if(des != null){
|
|
||||||
IPath rcProjPath = rc.getProjectRelativePath();
|
|
||||||
ICConfigurationDescription cfgDess[] = des.getConfigurations();
|
|
||||||
for (ICConfigurationDescription cfgDes : cfgDess) {
|
|
||||||
ICResourceDescription rcDescription = cfgDes.getResourceDescription(rcProjPath, true);
|
|
||||||
if(rcDescription != null){
|
|
||||||
try {
|
|
||||||
cfgDes.removeResourceDescription(rcDescription);
|
|
||||||
} catch (WriteAccessException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
} catch (CoreException e) {
|
|
||||||
CCorePlugin.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,38 +180,81 @@ public class ResourceChangeHandler extends ResourceChangeHandlerBase implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public void done() {
|
public void done() {
|
||||||
for(Iterator<Map.Entry<IProject, ICProjectDescription>> iter = fProjDesMap.entrySet().iterator(); iter.hasNext();){
|
// If the resource's project was moved / removed, don't consider the path for source entry removal
|
||||||
Map.Entry<IProject, ICProjectDescription> entry = iter.next();
|
for (Iterator<IResource> it = fMovedResources.keySet().iterator(); it.hasNext() ; ) {
|
||||||
if(fRemovedProjSet.contains(entry.getKey())){
|
if (fRemovedProjects.contains(it.next().getProject()))
|
||||||
iter.remove();
|
it.remove();
|
||||||
} else {
|
|
||||||
ICProjectDescription des = entry.getValue();
|
|
||||||
if(des != null && !des.isModified())
|
|
||||||
iter.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fProjDesMap.isEmpty()){
|
if (fMovedResources.isEmpty() && fProjDesMap.isEmpty())
|
||||||
CProjectDescriptionManager.runWspModification(new IWorkspaceRunnable(){
|
return;
|
||||||
|
|
||||||
public void run(IProgressMonitor monitor) throws CoreException {
|
// Handle moved and removed resources
|
||||||
for (Entry<IProject, ICProjectDescription> entry : fProjDesMap.entrySet()) {
|
// - reconciles both source-entry move & remove
|
||||||
IProject project = entry.getKey();
|
// - resource configuration move & remove
|
||||||
if(!project.isOpen())
|
// Run it in the Workspace, so we don't trip Bug 311189
|
||||||
continue;
|
CProjectDescriptionManager.runWspModification(new IWorkspaceRunnable(){
|
||||||
|
|
||||||
ICProjectDescription des = entry.getValue();
|
public void run(IProgressMonitor monitor) throws CoreException {
|
||||||
|
for (Map.Entry<IResource, IResource> entry : fMovedResources.entrySet()) {
|
||||||
|
IResource from = entry.getKey();
|
||||||
|
IResource to = entry.getValue();
|
||||||
|
// TODO: don't handle moves to a different project
|
||||||
|
assert(to == null || to.getProject().equals(from.getProject()));
|
||||||
|
|
||||||
|
// Bug 311189 -- if the resource still exists now, don't treat as a remove!
|
||||||
|
if (to == null && from.exists())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ICProjectDescription prjDesc = getProjectDescription(from);
|
||||||
|
if (prjDesc == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (ICConfigurationDescription cfg : prjDesc.getConfigurations()) {
|
||||||
try {
|
try {
|
||||||
fMngr.setProjectDescription(project, des);
|
// Handle source entry change
|
||||||
|
if (from instanceof IFolder) {
|
||||||
|
ICSourceEntry[] entries = cfg.getSourceEntries();
|
||||||
|
if (to != null)
|
||||||
|
entries = checkMove(from.getFullPath(), to.getFullPath(), entries);
|
||||||
|
else
|
||||||
|
entries = checkRemove(from.getFullPath(), entries);
|
||||||
|
// Update if there have been any changes
|
||||||
|
if(entries != null)
|
||||||
|
cfg.setSourceEntries(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We deliberately don't remove output entries. These directories may not exist when
|
||||||
|
// the project is created and may be deleted at during a normal project lifecycle
|
||||||
|
|
||||||
|
// Handle resource description change
|
||||||
|
ICResourceDescription rcDescription = cfg.getResourceDescription(from.getProjectRelativePath(), true);
|
||||||
|
if(rcDescription != null)
|
||||||
|
if (to != null)
|
||||||
|
rcDescription.setPath(to.getProjectRelativePath());
|
||||||
|
else
|
||||||
|
cfg.removeResourceDescription(rcDescription);
|
||||||
|
} catch (WriteAccessException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fMovedResources.clear();
|
||||||
|
|
||||||
}, new NullProgressMonitor());
|
// Save all the changed project descriptions
|
||||||
}
|
for (Entry<IProject, ICProjectDescription> entry : fProjDesMap.entrySet()) {
|
||||||
|
if(!entry.getKey().isAccessible())
|
||||||
|
continue;
|
||||||
|
try {
|
||||||
|
fMngr.setProjectDescription(entry.getKey(), entry.getValue());
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, new NullProgressMonitor());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue