| /******************************************************************************* |
| * Copyright (c) 2007, 2011 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 |
| * Anton Leherbauer (Wind River Systems) |
| * James Blackburn (Broadcom Corp.) |
| *******************************************************************************/ |
| package org.eclipse.cdt.internal.core; |
| |
| import java.lang.ref.Reference; |
| import java.lang.ref.SoftReference; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.concurrent.ConcurrentHashMap; |
| import java.util.concurrent.CopyOnWriteArraySet; |
| |
| import org.eclipse.cdt.core.CCorePlugin; |
| import org.eclipse.cdt.core.CDescriptorEvent; |
| import org.eclipse.cdt.core.ICDescriptor; |
| import org.eclipse.cdt.core.ICDescriptorListener; |
| import org.eclipse.cdt.core.ICDescriptorManager; |
| import org.eclipse.cdt.core.ICDescriptorOperation; |
| import org.eclipse.cdt.core.model.CoreModel; |
| import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; |
| import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; |
| import org.eclipse.cdt.core.settings.model.ICDescriptionDelta; |
| import org.eclipse.cdt.core.settings.model.ICProjectDescription; |
| import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener; |
| import org.eclipse.cdt.core.settings.model.ICSettingObject; |
| import org.eclipse.cdt.core.settings.model.extension.CConfigurationData; |
| import org.eclipse.cdt.internal.core.settings.model.CConfigurationDescriptionCache; |
| import org.eclipse.cdt.internal.core.settings.model.CConfigurationSpecSettings; |
| import org.eclipse.cdt.internal.core.settings.model.CProjectDescription; |
| import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager; |
| import org.eclipse.cdt.internal.core.settings.model.ExceptionFactory; |
| import org.eclipse.cdt.internal.core.settings.model.IInternalCCfgInfo; |
| import org.eclipse.cdt.internal.core.settings.model.PathEntryConfigurationDataProvider; |
| import org.eclipse.core.resources.IProject; |
| 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.IProgressMonitor; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.core.runtime.Status; |
| |
| /** |
| * CConfigBasedDescriptorManager |
| * |
| * ICDescriptor settings are set directly within the project description. |
| * |
| * The ICDescriptorManager can be used to fetch the current ICDescriptor |
| * for the project get and set settings in this module in a safe manner. |
| * |
| * This thread delegates operations to the particular CConfigBasedDescriptor |
| * being operated upon. Locking is performed per descriptor. This manager |
| * provides additional concurrency above any beyond that provided by |
| * {@link CoreModel#getProjectDescription(IProject)} as each project only |
| * has one ICDescriptor live at any time. This prevents concurrent modifications |
| * from overwriting changes made in other threads. |
| * |
| * Usage: |
| * Users should consider making changes to project ICDescriptors using an {@link ICDescriptorOperation} |
| * with the {@link #runDescriptorOperation} method. |
| * The ICDescriptor's returned for {@link #getDescriptor} are shared between multiple threads, |
| * but they are synchronized. This is safe as long as structural changes aren't made to the same |
| * project storage element from multiple threads. |
| * |
| * @see ICDescriptor for more |
| */ |
| final public class CConfigBasedDescriptorManager implements ICDescriptorManager { |
| private volatile static CConfigBasedDescriptorManager fInstance; |
| public static final String NULL_OWNER_ID = ""; //$NON-NLS-1$ |
| private static volatile Map<String, COwnerConfiguration> fOwnerConfigMap; |
| private volatile static ICProjectDescriptionListener fDescriptionListener; |
| |
| private Collection<ICDescriptorListener> fListeners = new CopyOnWriteArraySet<ICDescriptorListener>(); |
| |
| /** Map: IProjet -> CConfigBasedDescriptor weak reference <br /> |
| * Multiple threads operating concurrently will get the same shared |
| * ICDescriptor, however we don't keep a reference to this for longer |
| * than is necessary.*/ |
| final ConcurrentHashMap<IProject, Reference<CConfigBasedDescriptor>> fProjectDescriptorMap = new ConcurrentHashMap<IProject, Reference<CConfigBasedDescriptor>>(); |
| |
| private CConfigBasedDescriptorManager(){} |
| |
| public static CConfigBasedDescriptorManager getInstance(){ |
| if(fInstance == null){ |
| synchronized (CConfigBasedDescriptor.class) { |
| if(fInstance == null){ |
| fInstance = new CConfigBasedDescriptorManager(); |
| } |
| } |
| } |
| return fInstance; |
| } |
| |
| private static final COwnerConfiguration NULLCOwner = new COwnerConfiguration(NULL_OWNER_ID, |
| CCorePlugin.getResourceString("CDescriptorManager.internal_owner")); //$NON-NLS-1$ |
| |
| |
| /** |
| * Callback indicating that a project has moved |
| * @param fromProject |
| * @param toProject |
| */ |
| public void projectMove(IProject fromProject, IProject toProject) { |
| Reference<CConfigBasedDescriptor> ref = fProjectDescriptorMap.get(fromProject); |
| if (ref != null) |
| fProjectDescriptorMap.putIfAbsent(toProject, ref); |
| fProjectDescriptorMap.remove(fromProject); |
| } |
| |
| /** |
| * Callback to remove references the ICDescriptor when the project |
| * is closed or removed |
| * @param project |
| */ |
| public void projectClosedRemove(IProject project) { |
| fProjectDescriptorMap.remove(project); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#configure(org.eclipse.core.resources.IProject, java.lang.String) |
| */ |
| @Override |
| public void configure(IProject project, String id) throws CoreException { |
| if (id.equals(NULLCOwner.getOwnerID())) { |
| IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, |
| CCorePlugin.getResourceString("CDescriptorManager.exception.invalid_ownerID"), //$NON-NLS-1$ |
| (Throwable)null); |
| throw new CoreException(status); |
| } |
| |
| CConfigBasedDescriptor dr = null; |
| |
| // Only allow one IProject configure |
| synchronized (this) { |
| try { |
| dr = findDescriptor(project, false); |
| if (dr != null) { |
| dr.fLock.acquire(); |
| if (dr.getProjectOwner().getID().equals(NULLCOwner.getOwnerID())) { |
| // non owned descriptors are simply configure to the new owner no questions ask! |
| dr = updateDescriptor(project, dr, id); |
| } else if (!dr.getProjectOwner().getID().equals(id)) { |
| IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, CCorePlugin.STATUS_CDTPROJECT_EXISTS, |
| CCorePlugin.getResourceString("CDescriptorManager.exception.alreadyConfigured"), //$NON-NLS-1$ |
| (Throwable)null); |
| throw new CoreException(status); |
| } else { |
| return; // already configured with same owner. |
| } |
| } else { |
| dr = findDescriptor(project, true); |
| dr.fLock.acquire(); |
| dr = updateDescriptor(project, dr, id); |
| } |
| |
| dr.apply(true); |
| if(dr.isOperationStarted()) |
| dr.setOpEvent(new CDescriptorEvent(dr, CDescriptorEvent.CDTPROJECT_ADDED, 0)); |
| } finally { |
| if (dr != null) |
| dr.fLock.release(); |
| } |
| } |
| } |
| |
| /** |
| * Update the descriptor to the particular ownerId |
| * |
| * FIXME JBB don't twiddle CConfigBasedDescription state here. |
| * Creates the project description if non found. Locks the CConfigBasedDescriptor while this takes place |
| * @param project |
| * @param dr |
| * @param ownerId |
| * @return |
| * @throws CoreException |
| */ |
| private CConfigBasedDescriptor updateDescriptor(IProject project, CConfigBasedDescriptor dr, String ownerId) throws CoreException { |
| try { |
| dr.fLock.acquire(); |
| ICConfigurationDescription cfgDes = dr.getConfigurationDescription(); |
| CConfigurationSpecSettings settings = ((IInternalCCfgInfo)cfgDes).getSpecSettings(); |
| settings.setCOwner(ownerId); |
| COwner owner = settings.getCOwner(); |
| dr = findDescriptor(project, true); |
| owner.configure(project, dr); |
| return dr; |
| } finally { |
| dr.fLock.release(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#convert(org.eclipse.core.resources.IProject, java.lang.String) |
| */ |
| @Override |
| public void convert(IProject project, String id) throws CoreException { |
| CConfigBasedDescriptor dr = findDescriptor(project, false); |
| if(dr == null) |
| throw ExceptionFactory.createCoreException(CCorePlugin.getResourceString("CConfigBasedDescriptorManager.0")); //$NON-NLS-1$ |
| try { |
| dr.fLock.acquire(); |
| dr = updateDescriptor(project, dr, id); |
| dr.apply(true); |
| if(dr.isOperationStarted()) |
| dr.setOpEvent(new CDescriptorEvent(dr, CDescriptorEvent.CDTPROJECT_CHANGED, CDescriptorEvent.OWNER_CHANGED)); |
| } finally { |
| dr.fLock.release(); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#getDescriptor(org.eclipse.core.resources.IProject) |
| */ |
| @Override |
| public ICDescriptor getDescriptor(IProject project) throws CoreException { |
| return getDescriptor(project, true); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#getDescriptor(org.eclipse.core.resources.IProject, boolean) |
| */ |
| @Override |
| public ICDescriptor getDescriptor(IProject project, boolean create) throws CoreException { |
| return findDescriptor(project, create); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#addDescriptorListener(org.eclipse.cdt.core.ICDescriptorListener) |
| */ |
| @Override |
| public void addDescriptorListener(ICDescriptorListener listener) { |
| fListeners.add(listener); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#removeDescriptorListener(org.eclipse.cdt.core.ICDescriptorListener) |
| */ |
| @Override |
| public void removeDescriptorListener(ICDescriptorListener listener) { |
| fListeners.remove(listener); |
| } |
| |
| /* |
| * Run the descriptor operation. Lock the descriptor while this takes place... |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#runDescriptorOperation(org.eclipse.core.resources.IProject, org.eclipse.cdt.core.ICDescriptorOperation, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public void runDescriptorOperation(IProject project, ICDescriptorOperation op, IProgressMonitor monitor) |
| throws CoreException { |
| CConfigBasedDescriptor dr = findDescriptor(project, true); |
| if (dr == null) |
| throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, "Failed to create descriptor", null)); //$NON-NLS-1$ |
| |
| try { |
| dr.fLock.acquire(); |
| CDescriptorEvent event = null; |
| try { |
| dr.operationStart(); |
| op.execute(dr, monitor); |
| } finally { |
| event = dr.operationStop(); |
| } |
| dr.apply(false); |
| if(event != null) |
| CConfigBasedDescriptorManager.getInstance().notifyListeners(event); |
| } finally { |
| dr.fLock.release(); |
| } |
| } |
| |
| /* |
| * Runs a descriptor operation directly on an ICProjectDescription. |
| * |
| * (non-Javadoc) |
| * @see org.eclipse.cdt.core.ICDescriptorManager#runDescriptorOperation(org.eclipse.core.resources.IProject, org.eclipse.cdt.core.settings.model.ICProjectDescription, org.eclipse.cdt.core.ICDescriptorOperation, org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| @Override |
| public void runDescriptorOperation(IProject project, ICProjectDescription des, ICDescriptorOperation op, IProgressMonitor monitor) |
| throws CoreException { |
| // Ensure that only one of these is running on the project at any one time... |
| if(des.isReadOnly()) |
| throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, CCorePlugin.getResourceString("CConfigBasedDescriptorManager.2"), null)); //$NON-NLS-1$ |
| //create a new descriptor |
| CConfigBasedDescriptor dr = loadDescriptor((CProjectDescription)des); |
| if (dr == null) |
| throw new CoreException(new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, CCorePlugin.getResourceString("CConfigBasedDescriptorManager.3"), null)); //$NON-NLS-1$ |
| op.execute(dr, monitor); |
| // reconcile the changes into the passed in ICProjectDescription |
| CConfigBasedDescriptor.reconcile(dr, des); |
| } |
| |
| /** |
| * Fetch the ICDescriptor for the project. |
| * |
| * If there is no project description and create is specified, then a project |
| * description is created and a descriptor is returned. |
| * |
| * Otherwise a share ICDescriptor is returned for the given project |
| * |
| * @param project |
| * @param create create project description if existing description not found |
| * @throws CoreException |
| */ |
| private CConfigBasedDescriptor findDescriptor(IProject project, boolean create) throws CoreException { |
| if (!project.isAccessible() && !create) |
| return null; |
| CConfigBasedDescriptor dr = null; |
| Reference<CConfigBasedDescriptor> ref = fProjectDescriptorMap.get(project); |
| if (ref != null) |
| dr = ref.get(); |
| if (dr != null) |
| return dr; |
| |
| // Only create one descriptor at a time... |
| try { |
| // Use workspace root lock rule here as: |
| // CoreException in getProjectDescription can lead to a refresh holding a resource lock. |
| // Meanwhile the lock might be held by a resource notification thread. |
| |
| // FIXME JBB we really want to hold a resource lock here... |
| // However doing so changes the way ProjectDescriptions are created and makes CDescriptor tests fail |
| // Job.getJobManager().beginRule(ResourcesPlugin.getWorkspace().getRoot(), new NullProgressMonitor()); |
| |
| // if (fProjectDescriptorMap.get(project) != null && (dr = fProjectDescriptorMap.get(project).get()) != null) |
| // return dr; |
| // None found, create a new one based off of read-only project description |
| |
| CProjectDescription des = (CProjectDescription)CProjectDescriptionManager.getInstance().getProjectDescription(project, false); |
| if(des == null && create) |
| des = createProjDescriptionForDescriptor(project); |
| if(des != null) |
| dr = loadDescriptor(des); |
| |
| // Use the ConcurrentHashMap to ensure that only one descriptor is live at a time (for a given project...) |
| ref = fProjectDescriptorMap.putIfAbsent(project, new SoftReference<CConfigBasedDescriptor>(dr)); |
| if (ref != null) { |
| // Someone was here before us... |
| CConfigBasedDescriptor dr1 = ref.get(); |
| if (dr1 != null) |
| return dr1; |
| synchronized (this) { |
| ref = fProjectDescriptorMap.putIfAbsent(project, new SoftReference<CConfigBasedDescriptor>(dr)); |
| if (ref != null) { |
| // Someone was here before us... |
| dr1 = ref.get(); |
| if (dr1 != null) |
| return dr1; |
| } |
| fProjectDescriptorMap.put(project, new SoftReference<CConfigBasedDescriptor>(dr)); |
| } |
| } |
| } finally { |
| // Job.getJobManager().endRule(ResourcesPlugin.getWorkspace().getRoot()); |
| } |
| return dr; |
| } |
| |
| private static CProjectDescription createProjDescriptionForDescriptor(final IProject project) throws CoreException{ |
| final CProjectDescriptionManager mngr = CProjectDescriptionManager.getInstance(); |
| final CProjectDescription des = (CProjectDescription)mngr.createProjectDescription(project, false, true); |
| |
| CConfigurationData data = mngr.createDefaultConfigData(project, PathEntryConfigurationDataProvider.getDataFactory()); |
| des.createConfiguration(CCorePlugin.DEFAULT_PROVIDER_ID, data); |
| return des; |
| } |
| |
| /** |
| * Creates a new CConfigBasedDescriptor from the passed CProjectDescription |
| * |
| * static method does not alter any instance state |
| * |
| * @param des |
| * @return CConfigBasedDescriptor or null |
| * @throws CoreException |
| */ |
| private static CConfigBasedDescriptor loadDescriptor(CProjectDescription des) throws CoreException { |
| if (des == null) |
| throw ExceptionFactory.createCoreException("CProjectDescription des is null"); //$NON-NLS-1$ |
| |
| if(des.isReadOnly()) |
| des = (CProjectDescription)CProjectDescriptionManager.getInstance().getProjectDescription(des.getProject(), true); |
| |
| ICConfigurationDescription cfgDes = des.getDefaultSettingConfiguration(); |
| if (cfgDes instanceof CConfigurationDescriptionCache) { |
| des = (CProjectDescription)CProjectDescriptionManager.getInstance().getProjectDescription(des.getProject(), true); |
| cfgDes = des.getDefaultSettingConfiguration(); |
| } |
| |
| if (cfgDes != null){ |
| if(cfgDes.isReadOnly()) |
| throw ExceptionFactory.createCoreException(CCorePlugin.getResourceString("CConfigBasedDescriptorManager.4")); //$NON-NLS-1$ |
| return new CConfigBasedDescriptor(cfgDes); |
| } else if (!des.isCdtProjectCreating()){ |
| throw ExceptionFactory.createCoreException(CCorePlugin.getResourceString("CConfigBasedDescriptorManager.5")); //$NON-NLS-1$ |
| } |
| return null; |
| } |
| |
| public static synchronized COwnerConfiguration getOwnerConfiguration(String id) { |
| if (id.equals(NULLCOwner.getOwnerID())) |
| return NULLCOwner; |
| if (fOwnerConfigMap == null) |
| initializeOwnerConfiguration(); |
| COwnerConfiguration config = fOwnerConfigMap.get(id); |
| if (config == null) { // no install owner, lets create place holder config for it. |
| config = new COwnerConfiguration(id, CCorePlugin.getResourceString("CDescriptorManager.owner_not_Installed")); //$NON-NLS-1$ |
| fOwnerConfigMap.put(id, config); |
| } |
| return config; |
| } |
| |
| private static void initializeOwnerConfiguration() { |
| IExtensionPoint extpoint = Platform.getExtensionRegistry().getExtensionPoint(CCorePlugin.PLUGIN_ID, "CProject"); //$NON-NLS-1$ |
| IExtension extension[] = extpoint.getExtensions(); |
| fOwnerConfigMap = new HashMap<String, COwnerConfiguration>(extension.length); |
| for (int i = 0; i < extension.length; i++) { |
| IConfigurationElement element[] = extension[i].getConfigurationElements(); |
| for (int j = 0; j < element.length; j++) { |
| if (element[j].getName().equalsIgnoreCase("cproject")) { //$NON-NLS-1$ |
| fOwnerConfigMap.put(extension[i].getUniqueIdentifier(), new COwnerConfiguration(element[j])); |
| break; |
| } |
| } |
| } |
| } |
| |
| public void startup(){ |
| if (fDescriptionListener != null) |
| return; |
| fDescriptionListener = new ICProjectDescriptionListener(){ |
| @Override |
| public void handleEvent(CProjectDescriptionEvent event) { |
| doHandleEvent(event); |
| } |
| }; |
| CProjectDescriptionManager.getInstance().addCProjectDescriptionListener(fDescriptionListener, |
| CProjectDescriptionEvent.APPLIED | |
| CProjectDescriptionEvent.LOADED | |
| CProjectDescriptionEvent.DATA_APPLIED | |
| CProjectDescriptionEvent.ABOUT_TO_APPLY); |
| } |
| |
| public void shutdown(){ |
| if(fDescriptionListener != null) |
| CProjectDescriptionManager.getInstance().removeCProjectDescriptionListener(fDescriptionListener); |
| fDescriptionListener = null; |
| } |
| |
| /** |
| * Hand CProjectDescription events |
| * @param event |
| */ |
| private void doHandleEvent(CProjectDescriptionEvent event){ |
| CConfigBasedDescriptor dr = null; |
| |
| // Check for an in memory descriptor matching the current event's project |
| Reference<CConfigBasedDescriptor> ref = fProjectDescriptorMap.get(event.getProject()); |
| if (ref != null) |
| dr = ref.get(); |
| // If no delta, return |
| if (dr == null) |
| return; |
| |
| try { |
| dr.fLock.acquire(); |
| try { |
| switch(event.getEventType()){ |
| case CProjectDescriptionEvent.LOADED:{ |
| // the descriptor was requested while load process |
| CProjectDescription des = (CProjectDescription)CProjectDescriptionManager.getInstance().getProjectDescription(event.getProject(), true); |
| if(des != null){ |
| ICConfigurationDescription cfgDescription = des.getDefaultSettingConfiguration(); |
| if(cfgDescription != null){ |
| dr.updateConfiguration(cfgDescription); |
| dr.setDirty(false); |
| } |
| } |
| } |
| break; |
| case CProjectDescriptionEvent.ABOUT_TO_APPLY:{ |
| CProjectDescription des = (CProjectDescription)event.getNewCProjectDescription(); |
| if(des != null |
| && dr.getConfigurationDescription().getProjectDescription() != des){ |
| CConfigBasedDescriptor.reconcile(dr, des); |
| } |
| } |
| break; |
| case CProjectDescriptionEvent.DATA_APPLIED:{ |
| CProjectDescription des = (CProjectDescription)event.getNewCProjectDescription(); |
| if(des != null){ |
| CConfigBasedDescriptor.reconcile(dr, des); |
| } |
| } |
| break; |
| case CProjectDescriptionEvent.APPLIED: |
| CProjectDescription newDes = (CProjectDescription)event.getNewCProjectDescription(); |
| CProjectDescription oldDes = (CProjectDescription)event.getOldCProjectDescription(); |
| CDescriptorEvent desEvent = null; |
| ICConfigurationDescription updatedCfg = null; |
| if(oldDes == null){ |
| updatedCfg = newDes.getDefaultSettingConfiguration(); |
| desEvent = new CDescriptorEvent(dr, CDescriptorEvent.CDTPROJECT_ADDED, 0); |
| } else if(newDes == null) { |
| desEvent = new CDescriptorEvent(dr, CDescriptorEvent.CDTPROJECT_REMOVED, 0); |
| } else { |
| updatedCfg = newDes.getDefaultSettingConfiguration(); |
| ICConfigurationDescription newCfg = newDes.getDefaultSettingConfiguration(); |
| ICConfigurationDescription oldCfg = oldDes.getDefaultSettingConfiguration(); |
| int flags = 0; |
| if(oldCfg != null && newCfg != null){ |
| if(newCfg.getId().equals(oldCfg.getId())){ |
| ICDescriptionDelta cfgDelta = findCfgDelta(event.getProjectDelta(), newCfg.getId()); |
| if(cfgDelta != null){ |
| flags = cfgDelta.getChangeFlags() & (ICDescriptionDelta.EXT_REF | ICDescriptionDelta.OWNER); |
| } |
| } else { |
| flags = CProjectDescriptionManager.getInstance().calculateDescriptorFlags(newCfg, oldCfg); |
| } |
| } |
| |
| int drEventFlags = descriptionFlagsToDescriptorFlags(flags); |
| // if(drEventFlags != 0){ |
| desEvent = new CDescriptorEvent(dr, CDescriptorEvent.CDTPROJECT_CHANGED, drEventFlags); |
| // } |
| } |
| if(updatedCfg != null){ |
| CProjectDescription writableDes = (CProjectDescription)CProjectDescriptionManager.getInstance().getProjectDescription(event.getProject(), true); |
| ICConfigurationDescription indexCfg = writableDes.getDefaultSettingConfiguration(); |
| dr.updateConfiguration(indexCfg); |
| dr.setDirty(false); |
| } |
| notifyListeners(desEvent); |
| break; |
| } |
| |
| } catch (CoreException e){ |
| CCorePlugin.log(e); |
| } |
| } finally { |
| dr.fLock.release(); |
| } |
| } |
| |
| private int descriptionFlagsToDescriptorFlags(int flags){ |
| int result = 0; |
| if((flags & ICDescriptionDelta.EXT_REF) != 0){ |
| result |= CDescriptorEvent.EXTENSION_CHANGED; |
| } |
| if((flags & ICDescriptionDelta.OWNER) != 0){ |
| result |= CDescriptorEvent.OWNER_CHANGED; |
| } |
| return result; |
| } |
| |
| private ICDescriptionDelta findCfgDelta(ICDescriptionDelta delta, String id){ |
| if(delta == null) |
| return null; |
| ICDescriptionDelta children[] = delta.getChildren(); |
| for(int i = 0; i < children.length; i++){ |
| ICSettingObject s = children[i].getNewSetting(); |
| if(s != null && id.equals(s.getId())) |
| return children[i]; |
| } |
| return null; |
| } |
| |
| protected void notifyListeners(final CDescriptorEvent event) { |
| for (final ICDescriptorListener listener : fListeners) { |
| SafeRunner.run(new ISafeRunnable() { |
| |
| @Override |
| public void handleException(Throwable exception) { |
| IStatus status = new Status(IStatus.ERROR, CCorePlugin.PLUGIN_ID, -1, |
| CCorePlugin.getResourceString("CDescriptorManager.exception.listenerError"), exception); //$NON-NLS-1$ |
| CCorePlugin.log(status); |
| } |
| |
| @Override |
| public void run() throws Exception { |
| listener.descriptorChanged(event); |
| } |
| }); |
| } |
| } |
| |
| } |