mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-13 19:25:38 +02:00
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
This commit is contained in:
parent
c61a0ca618
commit
fcf6db2881
4 changed files with 108 additions and 57 deletions
|
@ -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.Configuration;
|
||||||
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
|
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo;
|
||||||
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
|
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.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
|
||||||
import org.eclipse.core.resources.IFolder;
|
import org.eclipse.core.resources.IFolder;
|
||||||
import org.eclipse.core.resources.IProject;
|
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++){
|
for(int i = 0; i < settings.length; i++){
|
||||||
ICLanguageSetting setting = settings[i];
|
ICLanguageSetting setting = settings[i];
|
||||||
ICLanguageSettingEntry[] entries = setting.getSettingEntries(ICLanguageSettingEntry.INCLUDE_PATH);
|
ICLanguageSettingEntry[] entries = setting.getSettingEntries(ICLanguageSettingEntry.INCLUDE_PATH);
|
||||||
|
BuildSystemTestHelper.checkDiff(entries, updatedEntries);
|
||||||
if(entries.length > 0){
|
if(entries.length > 0){
|
||||||
// ICLanguageSettingEntry updated[] = new ICLanguageSettingEntry[entries.length + 1];
|
// ICLanguageSettingEntry updated[] = new ICLanguageSettingEntry[entries.length + 1];
|
||||||
// System.arraycopy(entries, 0, updated, 1, entries.length);
|
// System.arraycopy(entries, 0, updated, 1, entries.length);
|
||||||
|
|
|
@ -161,9 +161,16 @@ public class CfgDiscoveredPathManager implements IResourceChangeListener {
|
||||||
|
|
||||||
PathInfo info = getCachedPathInfo(cInfo);
|
PathInfo info = getCachedPathInfo(cInfo);
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
IDiscoveredPathManager.IDiscoveredPathInfo baseInfo = loadPathInfo(project, context.getConfiguration(), cInfo);
|
synchronized (this) {
|
||||||
|
info = getCachedPathInfo(cInfo);
|
||||||
info = resolveCacheBaseDiscoveredInfo(cInfo, baseInfo);
|
|
||||||
|
if(info == null){
|
||||||
|
IDiscoveredPathManager.IDiscoveredPathInfo baseInfo = loadPathInfo(project, context.getConfiguration(), cInfo);
|
||||||
|
|
||||||
|
info = resolveCacheBaseDiscoveredInfo(cInfo, baseInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setCachedPathInfo(context, info);
|
// setCachedPathInfo(context, info);
|
||||||
// if(info instanceof DiscoveredPathInfo && !((DiscoveredPathInfo)info).isLoadded()){
|
// if(info instanceof DiscoveredPathInfo && !((DiscoveredPathInfo)info).isLoadded()){
|
||||||
// info = createPathInfo(project, context);
|
// info = createPathInfo(project, context);
|
||||||
|
|
|
@ -448,6 +448,10 @@ public class CProjectDescription implements ICProjectDescription, ICDataProxyCon
|
||||||
return fRootStorageElement;
|
return fRootStorageElement;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ICStorageElement doGetCachedRootStorageElement(){
|
||||||
|
return fRootStorageElement;
|
||||||
|
}
|
||||||
|
|
||||||
private ICSettingsStorage getStorageBase() throws CoreException{
|
private ICSettingsStorage getStorageBase() throws CoreException{
|
||||||
if(fStorage == null)
|
if(fStorage == null)
|
||||||
fStorage = new CStorage((InternalXmlStorageElement)getRootStorageElement());
|
fStorage = new CStorage((InternalXmlStorageElement)getRootStorageElement());
|
||||||
|
|
|
@ -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{
|
CProjectDescription checkExternalProjectFileModification(IResource rc) throws CoreException{
|
||||||
Map map = getProjectFileSerializationMap(false);
|
Map map = getProjectFileSerializationMap(false);
|
||||||
|
@ -453,8 +468,25 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager {
|
||||||
CProjectDescription des = (CProjectDescription)getProjectDescription(project, GET_IF_LOADDED);
|
CProjectDescription des = (CProjectDescription)getProjectDescription(project, GET_IF_LOADDED);
|
||||||
if(des == null || des.isLoadding())
|
if(des == null || des.isLoadding())
|
||||||
return null;
|
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 = (CProjectDescription)loadProjectDescription(project);
|
||||||
des = createWritableDescription(des);
|
des = createWritableDescription(des);
|
||||||
des.touch();
|
des.touch();
|
||||||
|
@ -1425,11 +1457,9 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ByteArrayOutputStream write(ICStorageElement element) throws CoreException {
|
||||||
private void serialize(IProject project, String file, ICStorageElement element) throws CoreException{
|
|
||||||
Document doc = getDocument(element);
|
Document doc = getDocument(element);
|
||||||
|
|
||||||
// Transform the document to something we can save in a file
|
|
||||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||||
try {
|
try {
|
||||||
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
Transformer transformer = TransformerFactory.newInstance().newTransformer();
|
||||||
|
@ -1439,59 +1469,67 @@ public class CProjectDescriptionManager implements ICProjectDescriptionManager {
|
||||||
DOMSource source = new DOMSource(doc);
|
DOMSource source = new DOMSource(doc);
|
||||||
StreamResult result = new StreamResult(stream);
|
StreamResult result = new StreamResult(stream);
|
||||||
transformer.transform(source, result);
|
transformer.transform(source, result);
|
||||||
|
|
||||||
// Save the document
|
return stream;
|
||||||
IFile projectFile = project.getFile(file);
|
|
||||||
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$
|
|
||||||
} else throw(e);
|
|
||||||
} else throw(e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
doneSaveProjectFile(project);
|
|
||||||
// Close the streams
|
|
||||||
stream.close();
|
|
||||||
} catch (TransformerConfigurationException e){
|
} catch (TransformerConfigurationException e){
|
||||||
throw ExceptionFactory.createCoreException(e);
|
throw ExceptionFactory.createCoreException(e);
|
||||||
} catch (TransformerException e) {
|
} catch (TransformerException e) {
|
||||||
throw ExceptionFactory.createCoreException(e);
|
throw ExceptionFactory.createCoreException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serialize(IProject project, String file, ICStorageElement element) throws CoreException{
|
||||||
|
try {
|
||||||
|
IFile projectFile = project.getFile(file);
|
||||||
|
ByteArrayOutputStream stream = write(element); //$NON-NLS-1$
|
||||||
|
|
||||||
|
String utfString = stream.toString("UTF-8"); //$NON-NLS-1$
|
||||||
|
aboutToSaveProjectFile(project);
|
||||||
|
|
||||||
|
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 {
|
||||||
|
projectFile.create(new ByteArrayInputStream(utfString.getBytes("UTF-8")), IResource.FORCE, new NullProgressMonitor()); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}finally{
|
||||||
|
doneSaveProjectFile(project);
|
||||||
|
stream.close();
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw ExceptionFactory.createCoreException(e);
|
throw ExceptionFactory.createCoreException(e);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue