diff options
author | Mikhail Sennikovsky | 2007-07-26 16:33:29 +0000 |
---|---|---|
committer | Mikhail Sennikovsky | 2007-07-26 16:33:29 +0000 |
commit | fcf6db28815c0bbc76d09ba39ad9bf421054537f (patch) | |
tree | f2a5b9858cb16b02dfc827520c20157a9db227d6 | |
parent | c61a0ca6182bcc4e246ac243af16541534da8a3d (diff) | |
download | org.eclipse.cdt-fcf6db28815c0bbc76d09ba39ad9bf421054537f.tar.gz org.eclipse.cdt-fcf6db28815c0bbc76d09ba39ad9bf421054537f.tar.xz org.eclipse.cdt-fcf6db28815c0bbc76d09ba39ad9bf421054537f.zip |
1. follow-up to fix for [Bug 196048] Updating .cproject from CVS does not cause reload of settings
2. initial fix for [Bug 196284] ConcurrentModificationException during getProjectDescription
4 files changed, 106 insertions, 55 deletions
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/projectmodel/tests/ProjectModelTests.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/projectmodel/tests/ProjectModelTests.java index 7f1d872740a..f83cafd0fb6 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/projectmodel/tests/ProjectModelTests.java +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/projectmodel/tests/ProjectModelTests.java @@ -50,6 +50,7 @@ import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.managedbuilder.internal.core.Configuration; import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo; import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject; +import org.eclipse.cdt.managedbuilder.testplugin.BuildSystemTestHelper; import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -402,6 +403,7 @@ public class ProjectModelTests extends TestCase implements IElementChangedListen for(int i = 0; i < settings.length; i++){ ICLanguageSetting setting = settings[i]; ICLanguageSettingEntry[] entries = setting.getSettingEntries(ICLanguageSettingEntry.INCLUDE_PATH); + BuildSystemTestHelper.checkDiff(entries, updatedEntries); if(entries.length > 0){ // ICLanguageSettingEntry updated[] = new ICLanguageSettingEntry[entries.length + 1]; // System.arraycopy(entries, 0, updated, 1, entries.length); diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgDiscoveredPathManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgDiscoveredPathManager.java index 0c20732e0a4..83040223322 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgDiscoveredPathManager.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/build/internal/core/scannerconfig/CfgDiscoveredPathManager.java @@ -161,9 +161,16 @@ public class CfgDiscoveredPathManager implements IResourceChangeListener { PathInfo info = getCachedPathInfo(cInfo); if (info == null) { - IDiscoveredPathManager.IDiscoveredPathInfo baseInfo = loadPathInfo(project, context.getConfiguration(), cInfo); - - info = resolveCacheBaseDiscoveredInfo(cInfo, baseInfo); + synchronized (this) { + info = getCachedPathInfo(cInfo); + + if(info == null){ + IDiscoveredPathManager.IDiscoveredPathInfo baseInfo = loadPathInfo(project, context.getConfiguration(), cInfo); + + info = resolveCacheBaseDiscoveredInfo(cInfo, baseInfo); + } + } + // setCachedPathInfo(context, info); // if(info instanceof DiscoveredPathInfo && !((DiscoveredPathInfo)info).isLoadded()){ // info = createPathInfo(project, context); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java index 6972da66ae6..e98bd179b68 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescription.java @@ -448,6 +448,10 @@ public class CProjectDescription implements ICProjectDescription, ICDataProxyCon return fRootStorageElement; } + ICStorageElement doGetCachedRootStorageElement(){ + return fRootStorageElement; + } + private ICSettingsStorage getStorageBase() throws CoreException{ if(fStorage == null) fStorage = new CStorage((InternalXmlStorageElement)getRootStorageElement()); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java index 84195f2a77d..dbfb173d268 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionManager.java @@ -441,6 +441,21 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { // } // } } + + private boolean streamsMatch(InputStream stream1, InputStream stream2) throws IOException{ + do{ + int i1 = stream1.read(); + int i2 = stream2.read(); + + if(i1 != i2){ + return false; + } else if (i1 == -1){ + break; + } + }while(true); + + return true; + } CProjectDescription checkExternalProjectFileModification(IResource rc) throws CoreException{ Map map = getProjectFileSerializationMap(false); @@ -453,8 +468,25 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { CProjectDescription des = (CProjectDescription)getProjectDescription(project, GET_IF_LOADDED); if(des == null || des.isLoadding()) return null; + + //check whether contents differ + try { + ICStorageElement oldEl = des.doGetCachedRootStorageElement(); + if(oldEl != null){ + InputStream newContents = getSharedProperty(project, STORAGE_FILE_NAME); + ByteArrayOutputStream oldOut = write(oldEl); + InputStream oldContents = new ByteArrayInputStream(oldOut.toByteArray()); + if(streamsMatch(newContents, oldContents)) + return null; + } + } catch (CoreException e){ + CCorePlugin.log(e); + //continue + } catch (IOException e) { + CCorePlugin.log(e); + //continue + } - //TODO: .cproject file is modified externally des = (CProjectDescription)loadProjectDescription(project); des = createWritableDescription(des); des.touch(); @@ -1425,11 +1457,9 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { } } - - private void serialize(IProject project, String file, ICStorageElement element) throws CoreException{ + private ByteArrayOutputStream write(ICStorageElement element) throws CoreException { Document doc = getDocument(element); - - // Transform the document to something we can save in a file + ByteArrayOutputStream stream = new ByteArrayOutputStream(); try { Transformer transformer = TransformerFactory.newInstance().newTransformer(); @@ -1439,59 +1469,67 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager { DOMSource source = new DOMSource(doc); StreamResult result = new StreamResult(stream); transformer.transform(source, result); - - // Save the document + + return stream; + } catch (TransformerConfigurationException e){ + throw ExceptionFactory.createCoreException(e); + } catch (TransformerException e) { + throw ExceptionFactory.createCoreException(e); + } + } + + private void serialize(IProject project, String file, ICStorageElement element) throws CoreException{ + try { IFile projectFile = project.getFile(file); - String utfString = stream.toString("UTF-8"); //$NON-NLS-1$ + ByteArrayOutputStream stream = write(element); //$NON-NLS-1$ + String utfString = stream.toString("UTF-8"); //$NON-NLS-1$ aboutToSaveProjectFile(project); - - if (projectFile.exists()) { - if (projectFile.isReadOnly()) { - // Inform Eclipse that we are intending to modify this file - // This will provide the user the opportunity, via UI prompts, to fetch the file from source code control - // reset a read-only file protection to write etc. - // If there is no shell, i.e. shell is null, then there will be no user UI interaction - - //TODO - //IStatus status = projectFile.getWorkspace().validateEdit(new IFile[]{projectFile}, shell); - - // If the file is still read-only, then we should not attempt the write, since it will - // just fail - just throw an exception, to be caught below, and inform the user - // For other non-successful status, we take our chances, attempt the write, and pass - // along any exception thrown - - //if (!status.isOK()) { - // if (status.getCode() == IResourceStatus.READ_ONLY_LOCAL) { - // stream.close(); - // throw new CoreException(status); - //} - //} - } - try { - projectFile.setContents(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ - } catch (CoreException e) { - if (projectFile.getLocation().toFile().isHidden()) { - String os = System.getProperty("os.name"); //$NON-NLS-1$ - if (os != null && os.startsWith("Win")) { //$NON-NLS-1$ - projectFile.delete(true, null); - projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ - CCorePlugin.log(e.getLocalizedMessage() + - "\n** Error occured because of file status <hidden>." + //$NON-NLS-1$ - "\n** This status is disabled now, to allow writing."); //$NON-NLS-1$ + + try { + if (projectFile.exists()) { + if (projectFile.isReadOnly()) { + // Inform Eclipse that we are intending to modify this file + // This will provide the user the opportunity, via UI prompts, to fetch the file from source code control + // reset a read-only file protection to write etc. + // If there is no shell, i.e. shell is null, then there will be no user UI interaction + + //TODO + //IStatus status = projectFile.getWorkspace().validateEdit(new IFile[]{projectFile}, shell); + + // If the file is still read-only, then we should not attempt the write, since it will + // just fail - just throw an exception, to be caught below, and inform the user + // For other non-successful status, we take our chances, attempt the write, and pass + // along any exception thrown + + //if (!status.isOK()) { + // if (status.getCode() == IResourceStatus.READ_ONLY_LOCAL) { + // stream.close(); + // throw new CoreException(status); + //} + //} + } + try { + projectFile.setContents(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ + } catch (CoreException e) { + if (projectFile.getLocation().toFile().isHidden()) { + String os = System.getProperty("os.name"); //$NON-NLS-1$ + if (os != null && os.startsWith("Win")) { //$NON-NLS-1$ + projectFile.delete(true, null); + projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ + CCorePlugin.log(e.getLocalizedMessage() + + "\n** Error occured because of file status <hidden>." + //$NON-NLS-1$ + "\n** This status is disabled now, to allow writing."); //$NON-NLS-1$ + } else throw(e); } else throw(e); - } else throw(e); + } + } else { + projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ } - } else { - projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$ + }finally{ + doneSaveProjectFile(project); + stream.close(); } - doneSaveProjectFile(project); - // Close the streams - stream.close(); - } catch (TransformerConfigurationException e){ - throw ExceptionFactory.createCoreException(e); - } catch (TransformerException e) { - throw ExceptionFactory.createCoreException(e); } catch (IOException e) { throw ExceptionFactory.createCoreException(e); } |