1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 01:15:29 +02:00

1. Bug-fixes for 175090 and 175091

2. Map is used to store the project-to-CProjectDescription associations instead of project session properties
3. Basis for functionality of preserving settings on resource rename/move.
This commit is contained in:
Mikhail Sennikovsky 2007-02-23 20:06:36 +00:00
parent b5eee56244
commit c391b1daf6
10 changed files with 752 additions and 157 deletions

View file

@ -98,7 +98,6 @@ import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.PluginVersionIdentifier;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
@ -118,7 +117,7 @@ import org.w3c.dom.NodeList;
*/
public class ManagedBuildManager extends AbstractCExtension implements IScannerInfoProvider {
private static final QualifiedName buildInfoProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "managedBuildInfo"); //$NON-NLS-1$
// private static final QualifiedName buildInfoProperty = new QualifiedName(ManagedBuilderCorePlugin.getUniqueIdentifier(), "managedBuildInfo"); //$NON-NLS-1$
private static final String ROOT_NODE_NAME = "ManagedProjectBuildInfo"; //$NON-NLS-1$
public static final String SETTINGS_FILE_NAME = ".cdtbuild"; //$NON-NLS-1$
private static final ITarget[] emptyTargets = new ITarget[0];
@ -217,6 +216,8 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
private static HashMap fSortedTools;
private static HashMap fSortedBuilders;
private static Map fInfoMap = new HashMap();
private static ISorter fToolChainSorter = new ISorter(){
public void sort() {
resortToolChains();
@ -1943,7 +1944,8 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
ManagedBuildManager.performValueHandlerEvent(configs[i], IManagedOptionValueHandler.EVENT_OPEN);
}
// Finish up
project.setSessionProperty(buildInfoProperty, buildInfo);
//project.setSessionProperty(buildInfoProperty, buildInfo);
setLoaddedBuildInfo(project, buildInfo);
}
} catch (Exception e) {
throw e;
@ -2445,9 +2447,13 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
return buildInfo;
}
public static void setLoaddedBuildInfo(IProject project, IManagedBuildInfo info) throws CoreException{
public synchronized static void setLoaddedBuildInfo(IProject project, IManagedBuildInfo info) throws CoreException{
// Associate the build info with the project for the duration of the session
project.setSessionProperty(buildInfoProperty, info);
//project.setSessionProperty(buildInfoProperty, info);
if(info != null)
fInfoMap.put(project, info);
else
fInfoMap.remove(project);
}
private static IManagedConfigElementProvider createConfigProvider(
@ -2563,9 +2569,9 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
return buildInfo;
}
private static ManagedBuildInfo getLoaddedBuildInfo(IProject project) throws CoreException{
synchronized static ManagedBuildInfo getLoaddedBuildInfo(IProject project) throws CoreException{
// Check if there is any build info associated with this project for this session
ManagedBuildInfo buildInfo = (ManagedBuildInfo)project.getSessionProperty(buildInfoProperty);
ManagedBuildInfo buildInfo = (ManagedBuildInfo)fInfoMap.get(project);//project.getSessionProperty(buildInfoProperty);
// Make sure that if a project has build info, that the info is not corrupted
if (buildInfo != null) {
buildInfo.updateOwner(project);
@ -4263,5 +4269,13 @@ public class ManagedBuildManager extends AbstractCExtension implements IScannerI
if(des != null)
CCorePlugin.getDefault().setPreferenceConfiguration(CFG_DATA_PROVIDER_ID, des);
}
static synchronized void updateLoaddedInfo(IProject fromProject, IProject toProject, IManagedBuildInfo info){
try {
setLoaddedBuildInfo(fromProject, null);
setLoaddedBuildInfo(toProject, info);
} catch (CoreException e) {
}
}
}

View file

@ -15,7 +15,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.make.core.scannerconfig.IDiscoveredPathManager;
import org.eclipse.cdt.make.core.scannerconfig.IExternalScannerInfoProvider;
import org.eclipse.cdt.make.core.scannerconfig.IScannerConfigBuilderInfo;
@ -27,27 +26,21 @@ import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil;
import org.eclipse.cdt.managedbuilder.internal.buildmodel.DbgUtil;
import org.eclipse.cdt.managedbuilder.internal.core.BuilderFactory;
import org.eclipse.cdt.managedbuilder.internal.core.GeneratedMakefileBuilder;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedMakeMessages;
import org.eclipse.cdt.managedbuilder.internal.core.ResourceChangeHandler;
import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildCPathEntryContainer;
import org.eclipse.cdt.managedbuilder.internal.scannerconfig.ManagedBuildPathEntryContainerInitializer;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.ISavedState;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Preferences;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.osgi.framework.BundleContext;
@ -74,7 +67,7 @@ public class ManagedBuilderCorePlugin extends Plugin {
private static ResourceChangeHandler listener;
private static ResourceChangeHandler2 listener;
private DiscoveredPathManager fDiscoveryPathManager;
@ -119,7 +112,15 @@ public class ManagedBuilderCorePlugin extends Plugin {
// elements
// IJobManager jobManager = Platform.getJobManager();
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
// IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
listener = new ResourceChangeHandler2();
ResourcesPlugin.getWorkspace().addResourceChangeListener(
listener,
IResourceChangeEvent.POST_CHANGE
| IResourceChangeEvent.PRE_DELETE
| IResourceChangeEvent.PRE_CLOSE
/*| IResourceChangeEvent.POST_BUILD*/);
/* try {
jobManager.beginRule(root, null);
@ -133,27 +134,27 @@ public class ManagedBuilderCorePlugin extends Plugin {
//The startResourceChangeHandling() might result in throwing an error
//see bug# 132001
//Always schedule a job
Job rcJob = new Job(ManagedMakeMessages.getResourceString("ManagedBuilderCorePlugin.resourceChangeHandlingInitializationJob")){ //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor) {
try{
startResourceChangeHandling();
} catch (CoreException e){
CCorePlugin.log(e);
return e.getStatus();
}
return new Status(
IStatus.OK,
ManagedBuilderCorePlugin.getUniqueIdentifier(),
IStatus.OK,
new String(),
null);
}
};
rcJob.setRule(root);
rcJob.setPriority(Job.INTERACTIVE);
rcJob.setSystem(true);
rcJob.schedule();
// Job rcJob = new Job(ManagedMakeMessages.getResourceString("ManagedBuilderCorePlugin.resourceChangeHandlingInitializationJob")){ //$NON-NLS-1$
// protected IStatus run(IProgressMonitor monitor) {
// try{
// startResourceChangeHandling();
// } catch (CoreException e){
// CCorePlugin.log(e);
// return e.getStatus();
// }
// return new Status(
// IStatus.OK,
// ManagedBuilderCorePlugin.getUniqueIdentifier(),
// IStatus.OK,
// new String(),
// null);
// }
// };
//
// rcJob.setRule(root);
// rcJob.setPriority(Job.INTERACTIVE);
// rcJob.setSystem(true);
// rcJob.schedule();
/*
} finally {
jobManager.endRule(root);
@ -166,23 +167,23 @@ public class ManagedBuilderCorePlugin extends Plugin {
* Throws CoreException if the methods fails to add a save participant.
* The resource change listener in not added in this case either.
*/
private void startResourceChangeHandling() throws CoreException{
// Set up a listener for resource change events
listener = new ResourceChangeHandler();
ISavedState lastState =
ResourcesPlugin.getWorkspace().addSaveParticipant(ManagedBuilderCorePlugin.this, listener);
ResourcesPlugin.getWorkspace().addResourceChangeListener(
listener,
IResourceChangeEvent.POST_CHANGE
| IResourceChangeEvent.PRE_DELETE
| IResourceChangeEvent.PRE_CLOSE
/*| IResourceChangeEvent.POST_BUILD*/);
if (lastState != null) {
lastState.processResourceChangeEvents(listener);
}
}
// private void startResourceChangeHandling() throws CoreException{
// // Set up a listener for resource change events
// listener = new ResourceChangeHandler();
// ISavedState lastState =
// ResourcesPlugin.getWorkspace().addSaveParticipant(ManagedBuilderCorePlugin.this, listener);
//
// ResourcesPlugin.getWorkspace().addResourceChangeListener(
// listener,
// IResourceChangeEvent.POST_CHANGE
// | IResourceChangeEvent.PRE_DELETE
// | IResourceChangeEvent.PRE_CLOSE
// /*| IResourceChangeEvent.POST_BUILD*/);
//
// if (lastState != null) {
// lastState.processResourceChangeEvents(listener);
// }
// }
/* (non-Javadoc)
* @see org.eclipse.core.runtime.Plugin#start(org.osgi.framework.BundleContext)

View file

@ -0,0 +1,84 @@
/*******************************************************************************
* Copyright (c) 2007 Intel 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:
* Intel Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.managedbuilder.core;
import org.eclipse.cdt.core.settings.model.util.ResourceChangeHandlerBase;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.runtime.CoreException;
class ResourceChangeHandler2 extends ResourceChangeHandlerBase{
private class RcMoveHandler implements IResourceMoveHandler {
public void done() {
}
public void handleProjectClose(IProject project) {
sendClose(project);
try {
ManagedBuildManager.setLoaddedBuildInfo(project, null);
} catch (CoreException e) {
}
}
public boolean handleResourceMove(IResource fromRc, IResource toRc) {
switch(fromRc.getType()){
case IResource.PROJECT:
IProject fromProject = fromRc.getProject();
IProject toProject = toRc.getProject();
ManagedBuildInfo info = (ManagedBuildInfo)ManagedBuildManager.getBuildInfo(fromProject, false);
if(info != null){
info.updateOwner(toRc);
ManagedBuildManager.updateLoaddedInfo(fromProject, toProject, info);
}
}
return false;
}
public boolean handleResourceRemove(IResource rc) {
switch(rc.getType()){
case IResource.PROJECT:
IProject project = rc.getProject();
sendClose(project);
try {
ManagedBuildManager.setLoaddedBuildInfo(project, null);
} catch (CoreException e) {
}
}
return false;
}
}
protected IResourceMoveHandler createResourceMoveHandler(
IResourceChangeEvent event) {
return new RcMoveHandler();
}
public void sendClose(IProject project){
sendClose(ManagedBuildManager.getBuildInfo(project,false));
}
private void sendClose(IManagedBuildInfo info){
if(info != null){
IManagedProject managedProj = info.getManagedProject();
if (managedProj != null) {
IConfiguration cfgs[] = managedProj.getConfigurations();
for(int i = 0; i < cfgs.length; i++)
ManagedBuildManager.performValueHandlerEvent(cfgs[i], IManagedOptionValueHandler.EVENT_CLOSE, true);
}
}
}
}

View file

@ -0,0 +1,154 @@
/*******************************************************************************
* Copyright (c) 2007 Intel 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:
* Intel Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.settings.model.util;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
public abstract class ResourceChangeHandlerBase implements IResourceChangeListener {
public interface IResourceMoveHandler {
boolean handleResourceMove(IResource fromRc, IResource toRc);
boolean handleResourceRemove(IResource rc);
void handleProjectClose(IProject project);
void done();
}
private IWorkspaceRoot fRoot = ResourcesPlugin.getWorkspace().getRoot();
private class DeltaVisitor implements IResourceDeltaVisitor{
// private IResourceDelta fRootDelta;
private Map fMoveMap = new HashMap();
private IResourceMoveHandler fHandler;
public DeltaVisitor(IResourceMoveHandler handler, IResourceDelta rootDelta){
fHandler = handler;
// fRootDelta = rootDelta;
}
private IResource getResource(IPath path, IResource baseResource){
switch(baseResource.getType()){
case IResource.FILE:
return fRoot.getFile(path);
case IResource.FOLDER:
return fRoot.getFolder(path);
case IResource.PROJECT:
return fRoot.getProject(path.segment(0));
case IResource.ROOT:
default:
throw new IllegalArgumentException();
}
}
private boolean checkInitHandleResourceMove(IResource fromRc, IResource toRc){
if(fMoveMap.put(fromRc, toRc) == null){
return fHandler.handleResourceMove(fromRc, toRc);
}
return true;
}
public boolean visit(IResourceDelta delta) throws CoreException {
IResource dResource = delta.getResource();
boolean resume = true;
boolean removed = false;
switch (delta.getKind()) {
case IResourceDelta.REMOVED :
removed = true;
case IResourceDelta.CHANGED :
int flags = delta.getFlags();
if ((flags & IResourceDelta.MOVED_TO) != 0) {
IPath path = delta.getMovedToPath();
if(path != null){
IResource toRc = getResource(path, dResource);
resume = checkInitHandleResourceMove(dResource, toRc);
}
break;
} else if((flags & IResourceDelta.MOVED_FROM) != 0){
IPath path = delta.getMovedFromPath();
if(path != null){
IResource fromRc = getResource(path, dResource);
resume = checkInitHandleResourceMove(fromRc, dResource);
}
break;
} else if (removed){
resume = fHandler.handleResourceRemove(dResource);
}
default:
break;
}
return resume; // visit the children
}
}
/*
* I R e s o u r c e C h a n g e L i s t e n e r
*/
/* (non-Javadoc)
*
* Handle the renaming and deletion of project resources
* This is necessary in order to update ResourceConfigurations and AdditionalInputs
*
* @see org.eclipse.core.resources.IResourceChangeListener#resourceChanged(org.eclipse.core.resources.IResourceChangeEvent)
*/
public void resourceChanged(IResourceChangeEvent event) {
if (event.getSource() instanceof IWorkspace) {
IResourceMoveHandler handler = createResourceMoveHandler(event);
switch (event.getType()) {
case IResourceChangeEvent.PRE_CLOSE:
handler.handleProjectClose((IProject)event.getResource());
break;
// case IResourceChangeEvent.PRE_DELETE :
// handler.handleResourceRemove(event.getResource());
// break;
case IResourceChangeEvent.POST_CHANGE :
IResourceDelta resDelta = event.getDelta();
if (resDelta == null) {
break;
}
try {
DeltaVisitor rcChecker = new DeltaVisitor(handler, resDelta);
resDelta.accept(rcChecker);
} catch (CoreException e) {
CCorePlugin.log(e);
}
break;
default :
break;
}
handler.done();
}
}
protected abstract IResourceMoveHandler createResourceMoveHandler(IResourceChangeEvent event);
}

View file

@ -1,5 +1,5 @@
###############################################################################
# Copyright (c) 2000, 2006 IBM Corporation and others.
# Copyright (c) 2000, 2007 IBM 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
@ -78,3 +78,6 @@ PathEntryManager.5=Referenced project is not accessible
PathEntryManager.6=Referenced project is not a C/C++ project
PathEntryManager.1=Workspace include path inaccessible ({0})
PathEntryManager.7=Workspace library path inaccessible ({0})
CProjectDescriptionManager.startRcChangeHandling=Initiating resource change handling..
CProjectDescriptionManager.serializing=Serialing CDT Project settings..

View file

@ -52,6 +52,7 @@ import org.eclipse.cdt.core.resources.IPathEntryStoreListener;
import org.eclipse.cdt.core.resources.PathEntryStoreChangedEvent;
import org.eclipse.cdt.core.settings.model.util.PathEntryResolveInfo;
import org.eclipse.cdt.core.settings.model.util.PathEntryResolveInfoElement;
import org.eclipse.cdt.internal.core.settings.model.AbstractCExtensionProxy;
import org.eclipse.cdt.internal.core.settings.model.ConfigBasedPathEntryStore;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
@ -1178,10 +1179,14 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
public synchronized IPathEntryStore getPathEntryStore(IProject project, boolean create) throws CoreException {
IPathEntryStore store = (IPathEntryStore)storeMap.get(project);
if (store == null && create == true) {
store = createPathEntryStore(project);
storeMap.put(project, store);
store.addPathEntryStoreListener(this);
if (store == null) {
if(create == true){
store = createPathEntryStore(project);
storeMap.put(project, store);
store.addPathEntryStoreListener(this);
}
} else if (store instanceof AbstractCExtensionProxy){
((AbstractCExtensionProxy)store).updateProject(project);
}
return store;
}

View file

@ -36,6 +36,12 @@ public abstract class AbstractCExtensionProxy implements ICProjectDescriptionLis
checkUpdateProvider(CProjectDescriptionManager.getInstance().getProjectDescription(fProject, false), false, false);
}
public void updateProject(IProject project){
IProject oldProj = fProject;
fProject = project;
if(oldProj == null || !oldProj.equals(fProject))
fInited = false;
}
private ICExtensionReference getRef(ICConfigurationDescription cfg, boolean update){
if(fExtPointId != null){
@ -151,8 +157,10 @@ public abstract class AbstractCExtensionProxy implements ICProjectDescriptionLis
force = true;
case CProjectDescriptionEvent.APPLIED:
ICProjectDescription des = event.getNewCProjectDescription();
if(des != null)
if(des != null){
updateProject(des.getProject());
return checkUpdateProvider(des, force, true);
}
break;
}

View file

@ -63,6 +63,10 @@ public class CProjectDescription implements ICProjectDescription, ICDataProxyCon
// loadActiveCfgId();
}
void updateProject(IProject project){
fProject = project;
}
void loadDatas(){
if(!fIsReadOnly || !fIsLoadding)
return;

View file

@ -21,6 +21,7 @@ import java.io.InputStream;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@ -77,13 +78,18 @@ import org.eclipse.cdt.internal.core.CConfigBasedDescriptorManager;
import org.eclipse.cdt.internal.core.envvar.ContributedEnvironment;
import org.eclipse.cdt.internal.core.model.CElementDelta;
import org.eclipse.cdt.internal.core.model.CModelManager;
import org.eclipse.cdt.internal.core.model.CoreModelMessages;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.ISavedState;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtension;
@ -120,7 +126,7 @@ public class CProjectDescriptionManager {
private static final String CONVERTED_CFG_ID_PREFIX = "converted.config"; //$NON-NLS-1$
private static final String STORAGE_FILE_NAME = ".cproject"; //$NON-NLS-1$
private static final QualifiedName PROJECT_DESCRCIPTION_PROPERTY = new QualifiedName(CCorePlugin.PLUGIN_ID, "projectDescription"); //$NON-NLS-1$
// private static final QualifiedName PROJECT_DESCRCIPTION_PROPERTY = new QualifiedName(CCorePlugin.PLUGIN_ID, "projectDescription"); //$NON-NLS-1$
private static final String ROOT_ELEMENT_NAME = "cproject"; //$NON-NLS-1$
private static final String VERSION_ELEMENT_NAME = "fileVersion"; //$NON-NLS-1$
public static final Version DESCRIPTION_VERSION = new Version("4.0"); //$NON-NLS-1$
@ -138,6 +144,8 @@ public class CProjectDescriptionManager {
public static final String DEFAULT_PROVIDER_ID = CCorePlugin.PLUGIN_ID + ".defaultConfigDataProvider"; //$NON-NLS-1$
private static final String DEFAULT_CFG_ID_PREFIX = CCorePlugin.PLUGIN_ID + ".default.config"; //$NON-NLS-1$
private static final String DEFAULT_CFG_NAME = "Configuration"; //$NON-NLS-1$
private static final QualifiedName SCANNER_INFO_PROVIDER_PROPERTY = new QualifiedName(CCorePlugin.PLUGIN_ID, "scannerInfoProvider"); //$NON-NLS-1$
private class CompositeSafeRunnable implements ISafeRunnable {
private List fRunnables = new ArrayList();
@ -159,6 +167,8 @@ public class CProjectDescriptionManager {
r.handleException(e);
if(fStopOnErr)
throw e;
else
r.handleException(e);
}
}
}
@ -182,10 +192,10 @@ public class CProjectDescriptionManager {
}
}
private class ProjectInfoHolder{
ICProjectDescription fDescription;
ScannerInfoProviderProxy fSIProvider;
}
// private class ProjectInfoHolder{
// CProjectDescription fDescription;
// ScannerInfoProviderProxy fSIProvider;
// }
private class ListenerDescriptor{
ICProjectDescriptionListener fListener;
@ -207,6 +217,8 @@ public class CProjectDescriptionManager {
private Map fPreferenceMap = new HashMap();
private CConfigBasedDescriptorManager fDescriptorManager;
private ThreadLocal fLoaddingDescriptions = new ThreadLocal();
private Map fDescriptionMap = new HashMap(); //calls to this map are "manually" synchronized with the CProjectDescriptionManager object lock;
private ResourceChangeHandler fRcChangeHandler;
// private CStorage fPrefCfgStorage;
private ICDataProxyContainer fPrefUpdater = new ICDataProxyContainer(){
@ -241,9 +253,58 @@ public class CProjectDescriptionManager {
}
public void startup(){
if(fDescriptorManager == null){
fDescriptorManager = CConfigBasedDescriptorManager.getInstance();
fDescriptorManager.startup();
if(fRcChangeHandler == null){
fRcChangeHandler = new ResourceChangeHandler();
ResourcesPlugin.getWorkspace().addResourceChangeListener(
fRcChangeHandler,
IResourceChangeEvent.POST_CHANGE
| IResourceChangeEvent.PRE_DELETE
| IResourceChangeEvent.PRE_CLOSE
/*| IResourceChangeEvent.POST_BUILD*/);
if(fDescriptorManager == null){
fDescriptorManager = CConfigBasedDescriptorManager.getInstance();
fDescriptorManager.startup();
}
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
Job rcJob = new Job(CoreModelMessages.getFormattedString("CProjectDescriptionManager.startRcChangeHandling")){ //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor) {
try{
startSaveParticipant();
} catch (CoreException e){
CCorePlugin.log(e);
return e.getStatus();
}
return new Status(
IStatus.OK,
CCorePlugin.PLUGIN_ID,
IStatus.OK,
new String(),
null);
}
};
rcJob.setRule(root);
rcJob.setPriority(Job.INTERACTIVE);
rcJob.setSystem(true);
rcJob.schedule();
}
}
/*
* This method adds a save participant and resource change listener
* Throws CoreException if the methods fails to add a save participant.
* The resource change listener in not added in this case either.
*/
private void startSaveParticipant() throws CoreException{
// Set up a listener for resource change events
ISavedState lastState =
ResourcesPlugin.getWorkspace().addSaveParticipant(CCorePlugin.getDefault(), fRcChangeHandler);
if (lastState != null) {
lastState.processResourceChangeEvents(fRcChangeHandler);
}
}
@ -251,6 +312,10 @@ public class CProjectDescriptionManager {
if(fDescriptorManager != null){
fDescriptorManager.shutdown();
}
if(fRcChangeHandler != null){
ResourcesPlugin.getWorkspace().removeResourceChangeListener(fRcChangeHandler);
}
}
private ICProjectDescription getDescriptionLoadding(IProject project){
@ -281,6 +346,10 @@ public class CProjectDescriptionManager {
}
public ICProjectDescription getProjectDescription(IProject project, boolean write){
return getProjectDescription(project, true, write);
}
public ICProjectDescription getProjectDescription(IProject project, boolean load, boolean write){
ICProjectDescription des = null;
des = getLoaddedDescription(project);
IProjectDescription eDes = null;
@ -288,7 +357,7 @@ public class CProjectDescriptionManager {
if(des == null)
des = getDescriptionLoadding(project);
if(des == null){
if(des == null && load && project.isOpen()){
try {
des = loadProjectDescription(project);
} catch (CoreException e) {
@ -461,8 +530,8 @@ public class CProjectDescriptionManager {
runWspModification(r, monitor);
}
private void runWspModification(final ISafeRunnable runnable, IProgressMonitor monitor){
IWorkspace wsp = ResourcesPlugin.getWorkspace();
public void runWspModification(final ISafeRunnable runnable, IProgressMonitor monitor){
final IWorkspace wsp = ResourcesPlugin.getWorkspace();
boolean scheduleRule = true;
if(!wsp.isTreeLocked()) {
ISchedulingRule rule = wsp.getRoot();
@ -470,11 +539,10 @@ public class CProjectDescriptionManager {
try{
mngr.beginRule(rule, monitor);
scheduleRule = false;
try {
runnable.run();
} catch (Exception e){
runnable.handleException(e);
}
runAtomic(runnable);
} catch (CoreException e) {
CCorePlugin.log(e);
} catch (Exception e) {
} finally {
mngr.endRule(rule);
@ -482,12 +550,13 @@ public class CProjectDescriptionManager {
}
if(scheduleRule){
Job job = new Job("info serialization"){
Job job = new Job(CoreModelMessages.getFormattedString("CProjectDescriptionManager.serializing")){ //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor) {
try {
runnable.run();
} catch (Exception e) {
runnable.handleException(e);
runAtomic(runnable);
} catch (CoreException e) {
CCorePlugin.log(e);
return e.getStatus();
}
return Status.OK_STATUS;
}
@ -499,6 +568,35 @@ public class CProjectDescriptionManager {
}
}
private void runAtomic(final ISafeRunnable r) throws CoreException{
IWorkspace wsp = ResourcesPlugin.getWorkspace();
try {
wsp.run(new IWorkspaceRunnable(){
public void run(IProgressMonitor monitor) throws CoreException {
try {
r.run();
} catch (Exception e){
throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, e.getMessage(), e));
}
}
}, wsp.getRoot(), IWorkspace.AVOID_UPDATE, new NullProgressMonitor());
} catch (CoreException e){
IStatus status = e.getStatus();
if(CCorePlugin.PLUGIN_ID.equals(status.getPlugin())){
Throwable t = status.getException();
if(t instanceof Exception){
r.handleException((Exception)t);
return;
}
}
throw e;
}
}
private ICProjectConverter getConverter(IProject project, String oldOwnerId, ICProjectDescription des){
CProjectConverterDesciptor[] converterDess = getConverterDescriptors();
ICProjectConverter converter = null;
@ -546,90 +644,105 @@ public class CProjectDescriptionManager {
return des;
}
private ICProjectDescription getLoaddedDescription(IProject project){
try {
ProjectInfoHolder holder = getInfoHolder(project);
if(holder != null)
return holder.fDescription;
} catch (CoreException e) {
}
return null;
public synchronized ICProjectDescription getLoaddedDescription(IProject project){
CProjectDescription des = (CProjectDescription)fDescriptionMap.get(project);
if(des != null)
des.updateProject(project);
return des;
//// try {
// ProjectInfoHolder holder = getInfoHolder(project);
// if(holder != null){
// CProjectDescription des = holder.fDescription;
// if(des != null)
// des.updateProject(project);
// return des;
// }
//// } catch (CoreException e) {
//// }
// return null;
}
private ProjectInfoHolder getInfoHolder(final IProject project) throws CoreException{
return (ProjectInfoHolder)project.getSessionProperty(PROJECT_DESCRCIPTION_PROPERTY);
}
// synchronized private ProjectInfoHolder getInfoHolder(final IProject project){
// return (ProjectInfoHolder)fProjectInfoMap.get(project);
//// return (ProjectInfoHolder)project.getSessionProperty(PROJECT_DESCRCIPTION_PROPERTY);
// }
public synchronized ScannerInfoProviderProxy getScannerInfoProviderProxy(IProject project){
ProjectInfoHolder holder = null;
try {
holder = getInfoHolder(project);
} catch (CoreException e) {
holder = new ProjectInfoHolder();
}
boolean needSet = false;
if(holder == null){
holder = new ProjectInfoHolder();
needSet = true;
ICProjectDescription des = getProjectDescription(project, false);
if(des == null){
return new ScannerInfoProviderProxy(project);
}
ScannerInfoProviderProxy provider = holder.fSIProvider;
ScannerInfoProviderProxy provider = (ScannerInfoProviderProxy)des.getSessionProperty(SCANNER_INFO_PROVIDER_PROPERTY);
if(provider == null){
provider = new ScannerInfoProviderProxy(project);
holder.fSIProvider = provider;
des.setSessionProperty(SCANNER_INFO_PROVIDER_PROPERTY, provider);
} else {
provider.updateProject(project);
}
if(needSet)
setInfoHolder(project, holder);
return provider;
}
private void setInfoHolder(final IProject project, final ProjectInfoHolder holder){
try {
project.setSessionProperty(PROJECT_DESCRCIPTION_PROPERTY, holder);
} catch (CoreException e){
CCorePlugin.log(e);
//TODO: externalize
final ProjectInfoHolder f = holder;
Job setDesJob = new Job("Set loadded description job"){ //$NON-NLS-1$
protected IStatus run(IProgressMonitor monitor){
try {
project.setSessionProperty(PROJECT_DESCRCIPTION_PROPERTY, f);
} catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
};
setDesJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
setDesJob.setPriority(Job.INTERACTIVE);
setDesJob.setSystem(true);
setDesJob.schedule();
}
}
// synchronized void setInfoHolder(final IProject project, final ProjectInfoHolder holder){
// if(holder != null)
// fProjectInfoMap.put(project, holder);
// else
// fProjectInfoMap.remove(project);
//// try {
//// project.setSessionProperty(PROJECT_DESCRCIPTION_PROPERTY, holder);
//// } catch (CoreException e){
//// CCorePlugin.log(e);
//// //TODO: externalize
//// final ProjectInfoHolder f = holder;
//// Job setDesJob = new Job("Set loadded description job"){ //$NON-NLS-1$
//// protected IStatus run(IProgressMonitor monitor){
//// try {
//// project.setSessionProperty(PROJECT_DESCRCIPTION_PROPERTY, f);
//// } catch (CoreException e) {
//// return e.getStatus();
//// }
//// return Status.OK_STATUS;
//// }
//// };
////
//// setDesJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
//// setDesJob.setPriority(Job.INTERACTIVE);
//// setDesJob.setSystem(true);
//// setDesJob.schedule();
//// }
// }
synchronized boolean setLoaddedDescription(final IProject project, ICProjectDescription des, boolean overwriteIfExists){
try {
ProjectInfoHolder holder = getInfoHolder(project);
boolean needSet = false;
if(holder == null){
holder = new ProjectInfoHolder();
needSet = true;
}
if(!overwriteIfExists && fDescriptionMap.get(project) != null)
return false;
if(des != null)
fDescriptionMap.put(project, des);
else
fDescriptionMap.remove(project);
boolean shouldOverwrite = overwriteIfExists || holder.fDescription == null;
if(shouldOverwrite){
holder.fDescription = des;
if(needSet){
setInfoHolder(project, holder);
}
}
return shouldOverwrite;
} catch (CoreException e) {
}
return false;
return true;
//// try {
// ProjectInfoHolder holder = getInfoHolder(project);
// boolean needSet = false;
// if(holder == null){
// holder = new ProjectInfoHolder();
// needSet = true;
// }
//
// boolean shouldOverwrite = overwriteIfExists || holder.fDescription == null;
// if(shouldOverwrite){
// holder.fDescription = (CProjectDescription)des;
// if(needSet){
// setInfoHolder(project, holder);
// }
// }
// return shouldOverwrite;
//// } catch (CoreException e) {
//// }
//// return false;
}
private ICProjectDescription loadProjectDescription(IProject project) throws CoreException{
@ -1989,13 +2102,6 @@ public class CProjectDescriptionManager {
return result;
}
private boolean compare(Object o1, Object o2){
if(o1 != null)
return o1.equals(o2);
return o2 == null;
}
/* public boolean entriesEqual(ICLanguageSettingEntry entries1[], ICLanguageSettingEntry entries2[]){
if(entries1.length != entries2.length)
return false;
@ -2723,5 +2829,4 @@ public class CProjectDescriptionManager {
return data != null && !PathEntryConfigurationDataProvider.isPathEntryData(data);
}
}

View file

@ -0,0 +1,217 @@
/*******************************************************************************
* Copyright (c) 2007 Intel 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:
* Intel Corporation - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.settings.model;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.ICResourceDescription;
import org.eclipse.cdt.core.settings.model.WriteAccessException;
import org.eclipse.cdt.core.settings.model.util.ResourceChangeHandlerBase;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISaveParticipant;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.NullProgressMonitor;
public class ResourceChangeHandler extends ResourceChangeHandlerBase implements ISaveParticipant {
CProjectDescriptionManager fMngr = CProjectDescriptionManager.getInstance();
private class RcMoveHandler implements IResourceMoveHandler {
Map fProjDesMap = new HashMap();
Set fRemovedProjSet = new HashSet();
public void handleProjectClose(IProject project) {
fMngr.setLoaddedDescription(project, null, true);
}
public boolean handleResourceMove(IResource fromRc, IResource toRc) {
boolean proceed = true;
IProject fromProject = fromRc.getProject();
IProject toProject = toRc.getProject();
switch(toRc.getType()){
case IResource.PROJECT:{
ICProjectDescription des = getProjectDescription(fromProject, false);
fRemovedProjSet.add(fromProject);
if(des != null){
((CProjectDescription)des).updateProject(toProject);
synchronized (fMngr) {
fMngr.setLoaddedDescription(fromProject, null, true);
fMngr.setLoaddedDescription(toProject, des, true);
}
fProjDesMap.put(toProject, des);
ICConfigurationDescription[] cfgs = des.getConfigurations();
for(int i = 0; i < cfgs.length; i++){
cfgs[i].getConfigurationData();
}
}
}
break;
case IResource.FOLDER:
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(int i = 0; i < cfgDess.length; i++){
ICResourceDescription rcDescription = cfgDess[i].getResourceDescription(fromRcProjPath, true);
if(rcDescription != null){
try {
rcDescription.setPath(toRcProjPath);
} catch (WriteAccessException e) {
// } catch (CoreException e) {
}
}
}
}
break;
}
}
return proceed;
}
private ICProjectDescription getProjectDescription(IResource rc, boolean load){
IProject project = rc.getProject();
ICProjectDescription des = (ICProjectDescription)fProjDesMap.get(project);
if(des == null){
des = fMngr.getProjectDescription(project, load, true);
fProjDesMap.put(project, des);
}
return des;
}
public boolean handleResourceRemove(IResource rc) {
boolean proceed = true;
IProject project = rc.getProject();
switch(rc.getType()){
case IResource.PROJECT:
fMngr.setLoaddedDescription(project, null, true);
fRemovedProjSet.add(project);
proceed = false;
break;
case IResource.FOLDER:
case IResource.FILE:
if(project.exists()){
ICProjectDescription des = getProjectDescription(project, true);
if(des != null){
IPath rcProjPath = rc.getProjectRelativePath();
ICConfigurationDescription cfgDess[] = des.getConfigurations();
for(int i = 0; i < cfgDess.length; i++){
ICResourceDescription rcDescription = cfgDess[i].getResourceDescription(rcProjPath, true);
if(rcDescription != null){
try {
cfgDess[i].removeResourceDescription(rcDescription);
} catch (WriteAccessException e) {
} catch (CoreException e) {
}
}
}
}
}
break;
}
return proceed;
}
public void done() {
for(Iterator iter = fProjDesMap.entrySet().iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
if(fRemovedProjSet.contains(entry.getKey())){
iter.remove();
} else {
ICProjectDescription des = (ICProjectDescription)entry.getValue();
if(des == null || !des.isModified())
iter.remove();
}
}
if(fProjDesMap.size() != 0){
fMngr.runWspModification(new ISafeRunnable(){
public void handleException(Throwable exception) {
CCorePlugin.log(exception);
}
public void run() throws Exception {
for(Iterator iter = fProjDesMap.entrySet().iterator(); iter.hasNext();){
Map.Entry entry = (Map.Entry)iter.next();
IProject project = (IProject)entry.getKey();
ICProjectDescription des = (ICProjectDescription)entry.getValue();
try {
fMngr.setProjectDescription(project, des);
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
}
}, new NullProgressMonitor());
}
}
}
protected IResourceMoveHandler createResourceMoveHandler(
IResourceChangeEvent event) {
return new RcMoveHandler();
}
/*
* I S a v e P a r t i c i p a n t
*/
/* (non-Javadoc)
* @see org.eclipse.core.resources.ISaveParticipant#saving(org.eclipse.core.resources.ISaveContext)
*/
public void saving(ISaveContext context) throws CoreException {
//Request a resource delta to be used on next activation.
context.needDelta();
}
/* (non-Javadoc)
* @see org.eclipse.core.resources.ISaveParticipant#doneSaving(org.eclipse.core.resources.ISaveContext)
*/
public void doneSaving(ISaveContext context) {
}
/* (non-Javadoc)
* @see org.eclipse.core.resources.ISaveParticipant#prepareToSave(org.eclipse.core.resources.ISaveContext)
*/
public void prepareToSave(ISaveContext context) throws CoreException {
}
/* (non-Javadoc)
* @see org.eclipse.core.resources.ISaveParticipant#rollback(org.eclipse.core.resources.ISaveContext)
*/
public void rollback(ISaveContext context) {
}
}