mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 22:52:11 +02:00
RESOLVED - bug 252966: ProjectDescription Storage: It should be possible to extend / override persistence mechanism
https://bugs.eclipse.org/bugs/show_bug.cgi?id=252966
This commit is contained in:
parent
8d8060f5af
commit
6b87d8c5bc
12 changed files with 1015 additions and 9 deletions
|
@ -0,0 +1,404 @@
|
|||
/**********************************************************************
|
||||
* Copyright (c) 2004, 2008 QNX Software Systems Ltd 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:
|
||||
* QNX Software Systems Ltd - initial API and implementation
|
||||
* Anton Leherbauer (Wind River Systems)
|
||||
* James Blackburn (Broadcom Corp)
|
||||
***********************************************************************/
|
||||
|
||||
package org.eclipse.cdt.core.cdescriptor.tests;
|
||||
|
||||
import junit.extensions.TestSetup;
|
||||
import junit.framework.Assert;
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.CCorePlugin;
|
||||
import org.eclipse.cdt.core.CDescriptorEvent;
|
||||
import org.eclipse.cdt.core.CProjectNature;
|
||||
import org.eclipse.cdt.core.ICDescriptor;
|
||||
import org.eclipse.cdt.core.ICDescriptorListener;
|
||||
import org.eclipse.cdt.core.ICDescriptorOperation;
|
||||
import org.eclipse.cdt.core.ICExtensionReference;
|
||||
import org.eclipse.cdt.core.ICOwnerInfo;
|
||||
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOMManager;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.IProjectDescription;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.IWorkspaceRunnable;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* This class exists because the tests in CDescriptorTests
|
||||
* are not fixed.
|
||||
* This class corresponds to the version of
|
||||
* CDescrptorTests before the changes made in cdt.core 5.1
|
||||
* (CVS version 1.12)
|
||||
*/
|
||||
public class CDescriptorOldTests extends TestCase {
|
||||
|
||||
static String projectId = CTestPlugin.PLUGIN_ID + ".TestProject";
|
||||
static IProject fProject;
|
||||
static CDescriptorListener listener = new CDescriptorListener();
|
||||
static CDescriptorEvent fLastEvent;
|
||||
|
||||
/**
|
||||
* Constructor for CDescriptorTest.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public CDescriptorOldTests(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
TestSuite suite = new TestSuite(CDescriptorOldTests.class.getName());
|
||||
|
||||
suite.addTest(new CDescriptorOldTests("testDescriptorCreation"));
|
||||
suite.addTest(new CDescriptorOldTests("testDescriptorOwner"));
|
||||
suite.addTest(new CDescriptorOldTests("testExtensionCreation"));
|
||||
suite.addTest(new CDescriptorOldTests("testExtensionGet"));
|
||||
suite.addTest(new CDescriptorOldTests("testExtensionData"));
|
||||
suite.addTest(new CDescriptorOldTests("testExtensionRemove"));
|
||||
suite.addTest(new CDescriptorOldTests("testProjectDataCreate"));
|
||||
suite.addTest(new CDescriptorOldTests("testProjectDataDelete"));
|
||||
suite.addTest(new CDescriptorOldTests("testConcurrentDescriptorCreation"));
|
||||
suite.addTest(new CDescriptorOldTests("testConcurrentDescriptorCreation2"));
|
||||
suite.addTest(new CDescriptorOldTests("testDeadlockDuringProjectCreation"));
|
||||
suite.addTest(new CDescriptorOldTests("testProjectStorageDelete"));
|
||||
|
||||
TestSetup wrapper = new TestSetup(suite) {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
oneTimeSetUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
oneTimeTearDown();
|
||||
}
|
||||
|
||||
};
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
private static void addNatureToProject(IProject proj, String natureId, IProgressMonitor monitor) throws CoreException {
|
||||
IProjectDescription description = proj.getDescription();
|
||||
String[] prevNatures = description.getNatureIds();
|
||||
String[] newNatures = new String[prevNatures.length + 1];
|
||||
System.arraycopy(prevNatures, 0, newNatures, 0, prevNatures.length);
|
||||
newNatures[prevNatures.length] = natureId;
|
||||
description.setNatureIds(newNatures);
|
||||
proj.setDescription(description, monitor);
|
||||
}
|
||||
|
||||
static public class CDescriptorListener implements ICDescriptorListener {
|
||||
|
||||
public void descriptorChanged(CDescriptorEvent event) {
|
||||
fLastEvent = event;
|
||||
}
|
||||
}
|
||||
|
||||
static void oneTimeSetUp() throws Exception {
|
||||
CTestPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
IWorkspaceRoot root = CTestPlugin.getWorkspace().getRoot();
|
||||
IProject project = root.getProject("testDescriptorProject");
|
||||
if (!project.exists()) {
|
||||
project.create(null);
|
||||
} else {
|
||||
project.refreshLocal(IResource.DEPTH_INFINITE, null);
|
||||
}
|
||||
if (!project.isOpen()) {
|
||||
project.open(null);
|
||||
}
|
||||
CCorePlugin.getDefault().getCDescriptorManager().addDescriptorListener(listener);
|
||||
if (!project.hasNature(CProjectNature.C_NATURE_ID)) {
|
||||
addNatureToProject(project, CProjectNature.C_NATURE_ID, null);
|
||||
}
|
||||
fProject = project;
|
||||
}
|
||||
}, null);
|
||||
}
|
||||
|
||||
static void oneTimeTearDown() throws Exception {
|
||||
fProject.delete(true, true, null);
|
||||
}
|
||||
|
||||
public void testDescriptorCreation() throws Exception {
|
||||
CTestPlugin.getWorkspace().run(new IWorkspaceRunnable() {
|
||||
|
||||
public void run(IProgressMonitor monitor) throws CoreException {
|
||||
CCorePlugin.getDefault().mapCProjectOwner(fProject, projectId, false);
|
||||
}
|
||||
}, null);
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
|
||||
Assert.assertNotNull(fLastEvent);
|
||||
Assert.assertEquals(fLastEvent.getDescriptor(), desc);
|
||||
Assert.assertEquals(fLastEvent.getType(), CDescriptorEvent.CDTPROJECT_ADDED);
|
||||
Assert.assertEquals(fLastEvent.getFlags(), 0);
|
||||
fLastEvent = null;
|
||||
|
||||
Assert.assertEquals(fProject, desc.getProject());
|
||||
Assert.assertEquals("*", desc.getPlatform());
|
||||
}
|
||||
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185930
|
||||
public void testConcurrentDescriptorCreation() throws Exception {
|
||||
fProject.close(null);
|
||||
fProject.open(null);
|
||||
Thread t= new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
} catch (CoreException exc) {
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
t.join();
|
||||
|
||||
Element data = desc.getProjectData("testElement0");
|
||||
data.appendChild(data.getOwnerDocument().createElement("test"));
|
||||
desc.saveProjectData();
|
||||
fLastEvent = null;
|
||||
}
|
||||
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185930
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=193503
|
||||
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=196118
|
||||
public void testConcurrentDescriptorCreation2() throws Exception {
|
||||
int lastLength = 0;
|
||||
for (int i=0; i<200; ++i) {
|
||||
final int indexi = i;
|
||||
PDOMManager pdomMgr= (PDOMManager)CCorePlugin.getIndexManager();
|
||||
pdomMgr.shutdown();
|
||||
fProject.close(null);
|
||||
fProject.open(null);
|
||||
pdomMgr.startup().schedule();
|
||||
ICDescriptor desc= CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
if (lastLength == 0)
|
||||
lastLength = countChildElements(desc.getProjectData("testElement"));
|
||||
final Throwable[] exception= new Throwable[10];
|
||||
Thread[] threads= new Thread[10];
|
||||
for (int j = 0; j < 10; j++) {
|
||||
final int indexj = j;
|
||||
Thread t= new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ICDescriptorOperation operation= new ICDescriptorOperation() {
|
||||
public void execute(ICDescriptor descriptor, IProgressMonitor monitor) throws CoreException {
|
||||
assertFalse(descriptor.getConfigurationDescription().isReadOnly());
|
||||
Element data = descriptor.getProjectData("testElement");
|
||||
String test = "test"+(indexi*10 + indexj);
|
||||
data.appendChild(data.getOwnerDocument().createElement(test));
|
||||
assertFalse(descriptor.getConfigurationDescription().isReadOnly());
|
||||
// BUG196118 the model cached in memory doesn't reflect the contents of .cproject
|
||||
//
|
||||
// descriptor.saveProjectData() doesn't actually save despite what the API says
|
||||
// see CConfigBasedDescriptor.fApplyOnChange
|
||||
// ((CConfigBasedDescriptor)descriptor).apply(false);
|
||||
// System.out.println("Saved " + test);
|
||||
}};
|
||||
CCorePlugin.getDefault().getCDescriptorManager().runDescriptorOperation(fProject, operation, null);
|
||||
ICDescriptor descriptor = CCorePlugin.getDefault().getCDescriptorManager().getDescriptor(fProject);
|
||||
// perform apply outside descriptor operation to avoid deadlock - http://bugs.eclipse.org/241288
|
||||
descriptor.saveProjectData();
|
||||
} catch (Throwable exc) {
|
||||
exception[indexj]= exc;
|
||||
exc.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
threads[j] = t;
|
||||
}
|
||||
for (int j = 0; j < threads.length; j++) {
|
||||
if (threads[j] != null) {
|
||||
threads[j].join();
|
||||
}
|
||||
assertNull("Exception occurred: "+exception[j], exception[j]);
|
||||
}
|
||||
desc= CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
int lengthAfter = countChildElements(desc.getProjectData("testElement"));
|
||||
lastLength += threads.length; // Update last lengths to what we expect
|
||||
assertEquals("Iteration count: " + i, lastLength, lengthAfter);
|
||||
|
||||
fLastEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of Node.ELEMENT_NODE elements which are a
|
||||
* direct descendent of the parent Element.
|
||||
* Other nodes (e.g. Text) are ignored
|
||||
* @param parent
|
||||
* @return
|
||||
*/
|
||||
private int countChildElements(Element parent) {
|
||||
int numElements = 0;
|
||||
NodeList childNodes = parent.getChildNodes();
|
||||
for (int k = 0 ; k < childNodes.getLength() ; k++)
|
||||
if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE)
|
||||
numElements ++;
|
||||
return numElements;
|
||||
}
|
||||
|
||||
public void testDeadlockDuringProjectCreation() throws Exception {
|
||||
for (int i=0; i < 10; ++i) {
|
||||
oneTimeTearDown();
|
||||
oneTimeSetUp();
|
||||
Thread t= new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
Element data = desc.getProjectData("testElement0");
|
||||
data.appendChild(data.getOwnerDocument().createElement("test"));
|
||||
desc.saveProjectData();
|
||||
} catch (CoreException exc) {
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
Element data = desc.getProjectData("testElement0");
|
||||
data.appendChild(data.getOwnerDocument().createElement("test"));
|
||||
desc.saveProjectData();
|
||||
t.join();
|
||||
|
||||
fLastEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void testDescriptorOwner() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
ICOwnerInfo owner = desc.getProjectOwner();
|
||||
Assert.assertEquals(projectId, owner.getID());
|
||||
Assert.assertEquals("*", owner.getPlatform());
|
||||
Assert.assertEquals("C/C++ Test Project", owner.getName());
|
||||
}
|
||||
|
||||
public void testDescriptorConversion() {
|
||||
|
||||
}
|
||||
|
||||
public void testExtensionCreation() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
ICExtensionReference extRef = desc.create("org.eclipse.cdt.testextension", "org.eclipse.cdt.testextensionID");
|
||||
|
||||
Assert.assertNotNull(fLastEvent);
|
||||
Assert.assertEquals(fLastEvent.getDescriptor(), desc);
|
||||
Assert.assertEquals(fLastEvent.getType(), CDescriptorEvent.CDTPROJECT_CHANGED);
|
||||
Assert.assertEquals(fLastEvent.getFlags(), CDescriptorEvent.EXTENSION_CHANGED);
|
||||
fLastEvent = null;
|
||||
|
||||
Assert.assertEquals("org.eclipse.cdt.testextension", extRef.getExtension());
|
||||
Assert.assertEquals("org.eclipse.cdt.testextensionID", extRef.getID());
|
||||
}
|
||||
|
||||
public void testExtensionGet() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
ICExtensionReference extRef[] = desc.get("org.eclipse.cdt.testextension");
|
||||
|
||||
Assert.assertEquals("org.eclipse.cdt.testextension", extRef[0].getExtension());
|
||||
Assert.assertEquals("org.eclipse.cdt.testextensionID", extRef[0].getID());
|
||||
}
|
||||
|
||||
public void testExtensionData() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
ICExtensionReference extRef[] = desc.get("org.eclipse.cdt.testextension");
|
||||
extRef[0].setExtensionData("testKey", "testValue");
|
||||
|
||||
Assert.assertNotNull(fLastEvent);
|
||||
Assert.assertEquals(fLastEvent.getDescriptor(), desc);
|
||||
Assert.assertEquals(fLastEvent.getType(), CDescriptorEvent.CDTPROJECT_CHANGED);
|
||||
Assert.assertEquals(fLastEvent.getFlags(), 0);
|
||||
fLastEvent = null;
|
||||
|
||||
Assert.assertEquals("testValue", extRef[0].getExtensionData("testKey"));
|
||||
extRef[0].setExtensionData("testKey", null);
|
||||
Assert.assertEquals(null, extRef[0].getExtensionData("testKey"));
|
||||
}
|
||||
|
||||
public void testExtensionRemove() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
ICExtensionReference extRef[] = desc.get("org.eclipse.cdt.testextension");
|
||||
desc.remove(extRef[0]);
|
||||
|
||||
Assert.assertNotNull(fLastEvent);
|
||||
Assert.assertEquals(fLastEvent.getDescriptor(), desc);
|
||||
Assert.assertEquals(fLastEvent.getType(), CDescriptorEvent.CDTPROJECT_CHANGED);
|
||||
Assert.assertEquals(fLastEvent.getFlags(), CDescriptorEvent.EXTENSION_CHANGED);
|
||||
fLastEvent = null;
|
||||
|
||||
}
|
||||
|
||||
public void testProjectDataCreate() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
Element data = desc.getProjectData("testElement");
|
||||
data.appendChild(data.getOwnerDocument().createElement("test"));
|
||||
desc.saveProjectData();
|
||||
|
||||
Assert.assertNotNull(fLastEvent);
|
||||
Assert.assertEquals(fLastEvent.getDescriptor(), desc);
|
||||
Assert.assertEquals(fLastEvent.getType(), CDescriptorEvent.CDTPROJECT_CHANGED);
|
||||
Assert.assertEquals(fLastEvent.getFlags(), 0);
|
||||
fLastEvent = null;
|
||||
}
|
||||
|
||||
public void testProjectDataDelete() throws Exception {
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
Element data = desc.getProjectData("testElement");
|
||||
NodeList list = data.getElementsByTagName("test");
|
||||
Assert.assertEquals(1, list.getLength());
|
||||
data.removeChild(data.getFirstChild());
|
||||
desc.saveProjectData();
|
||||
|
||||
Assert.assertNotNull(fLastEvent);
|
||||
Assert.assertEquals(fLastEvent.getDescriptor(), desc);
|
||||
Assert.assertEquals(fLastEvent.getType(), CDescriptorEvent.CDTPROJECT_CHANGED);
|
||||
Assert.assertEquals(fLastEvent.getFlags(), 0);
|
||||
fLastEvent = null;
|
||||
}
|
||||
|
||||
public void testProjectStorageDelete() throws Exception {
|
||||
// 1st Add an item
|
||||
ICDescriptor desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
Element data = desc.getProjectData("testElement");
|
||||
data.appendChild(data.getOwnerDocument().createElement("test"));
|
||||
desc.saveProjectData();
|
||||
|
||||
// 2nd remove the storage element containing it
|
||||
desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
data = desc.getProjectData("testElement");
|
||||
data.getParentNode().removeChild(data);
|
||||
desc.saveProjectData();
|
||||
|
||||
// 3rd check the item no longer exists
|
||||
desc = CCorePlugin.getDefault().getCProjectDescription(fProject, true);
|
||||
data = desc.getProjectData("testElement");
|
||||
assertTrue(data.getChildNodes().getLength() == 0);
|
||||
fLastEvent = null;
|
||||
}
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ import junit.framework.Test;
|
|||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorTests;
|
||||
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorOldTests;
|
||||
import org.eclipse.cdt.core.internal.errorparsers.tests.ErrorParserTests;
|
||||
import org.eclipse.cdt.core.internal.tests.PositionTrackerTests;
|
||||
import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
|
||||
|
@ -56,6 +57,7 @@ public class AutomatedIntegrationSuite extends TestSuite {
|
|||
|
||||
// Add all success tests
|
||||
suite.addTest(CDescriptorTests.suite());
|
||||
suite.addTest(CDescriptorOldTests.suite());
|
||||
suite.addTest(ErrorParserTests.suite());
|
||||
suite.addTest(ParserTestSuite.suite());
|
||||
suite.addTest(AllCoreTests.suite());
|
||||
|
|
|
@ -17,6 +17,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
|
||||
/**
|
||||
* This interface represents the manager of CDT Project descriptions.
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICProjectDescriptionManager {
|
||||
/*
|
||||
|
@ -42,6 +44,7 @@ public interface ICProjectDescriptionManager {
|
|||
/**
|
||||
* Flag indicating that a new empty ICProjectDescription should be created and returned
|
||||
* (irrespective of whether one already exists)
|
||||
* @since 5.1
|
||||
*/
|
||||
public static final int GET_EMPTY_PROJECT_DESCRIPTION = 1 << 4;
|
||||
/**
|
||||
|
@ -49,6 +52,7 @@ public interface ICProjectDescriptionManager {
|
|||
* i.e. a description should be returned irrespective of whether one already exists.
|
||||
* If the project already has a description and !{@link #GET_EMPTY_PROJECT_DESCRIPTION}
|
||||
* the existing description will be returned, otherwise a new description is returned
|
||||
* @since 5.1
|
||||
*/
|
||||
public static final int GET_CREATE_DESCRIPTION = 1 << 5;
|
||||
/**
|
||||
|
@ -58,6 +62,7 @@ public interface ICProjectDescriptionManager {
|
|||
*
|
||||
* @see #GET_CREATE_DESCRIPTION
|
||||
* @see ICProjectDescription#isCdtProjectCreating()
|
||||
* @since 5.1
|
||||
*/
|
||||
public static final int PROJECT_CREATING = 1 << 6;
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.settings.model;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.cdt.core.ICDescriptor;
|
||||
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
|
||||
import org.eclipse.cdt.core.settings.model.extension.CConfigurationDataProvider;
|
||||
|
@ -44,6 +42,9 @@ import org.eclipse.core.runtime.IProgressMonitor;
|
|||
* @see ICProjectDescription
|
||||
* @see ICConfigurationDescription
|
||||
* @see ICDescriptor
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICSettingsStorage {
|
||||
/**
|
||||
|
@ -80,18 +81,21 @@ public interface ICSettingsStorage {
|
|||
* @param el ICStorageElement to be imported
|
||||
* @return ICStorageElement representing the imported storage
|
||||
* @throws UnsupportedOperationException
|
||||
* @since 5.1
|
||||
*/
|
||||
public ICStorageElement importStorage(String id, ICStorageElement el) throws UnsupportedOperationException, CoreException;
|
||||
|
||||
/**
|
||||
* Returns whether any non-persisted changes exist in this tree
|
||||
* @return boolean indicating whether any elements in this tree have been modified
|
||||
* @since 5.1
|
||||
*/
|
||||
public boolean isModified();
|
||||
|
||||
/**
|
||||
* Return whether this Settings Storage is currently read only
|
||||
* @return whether this storage is readonly
|
||||
* @since 5.1
|
||||
*/
|
||||
public boolean isReadOnly();
|
||||
|
||||
|
@ -100,6 +104,7 @@ public interface ICSettingsStorage {
|
|||
* then modified flag will not be reset
|
||||
* @param readOnly
|
||||
* @param keepModify
|
||||
* @since 5.1
|
||||
*/
|
||||
void setReadOnly(boolean readOnly, boolean keepModify);
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ import org.eclipse.core.runtime.CoreException;
|
|||
* @see ICSettingsStorage
|
||||
* @see ICProjectDescription
|
||||
* @see ICConfigurationDescription
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICStorageElement {
|
||||
|
||||
|
@ -98,6 +99,7 @@ public interface ICStorageElement {
|
|||
/**
|
||||
* Returns true if this storage element has child ICStorageElements
|
||||
* @return boolean indicating whether this ICStorageElement has children
|
||||
* @since 5.1
|
||||
*/
|
||||
boolean hasChildren();
|
||||
|
||||
|
@ -152,6 +154,7 @@ public interface ICStorageElement {
|
|||
* getParent() of the clone should be equal to the original element.getParent().
|
||||
* However the clone() doesn't appear in the parent's getChildren() array.
|
||||
* @return ICStorageElement deep copy of this ICStorageElement
|
||||
* @since 5.1
|
||||
*/
|
||||
ICStorageElement createCopy() throws UnsupportedOperationException, CoreException;
|
||||
|
||||
|
@ -175,6 +178,7 @@ public interface ICStorageElement {
|
|||
* equal between the two ICStorageElements
|
||||
* @param other
|
||||
* @return boolean indicating equality
|
||||
* @since 5.1
|
||||
*/
|
||||
boolean equals(ICStorageElement other);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ import org.w3c.dom.NodeList;
|
|||
*
|
||||
* This allows importing of old style Xml trees into ICStorageElement
|
||||
* based project descriptions
|
||||
*
|
||||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @since 5.1
|
||||
*/
|
||||
public class XmlStorageUtil {
|
||||
|
||||
|
|
|
@ -138,7 +138,18 @@ public abstract class ResourceChangeHandlerBase implements IResourceChangeListen
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @nooverride This method is not intended to be re-implemented or extended by clients.
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
*/
|
||||
protected void doHahdleResourceMove(IResourceChangeEvent event, IResourceMoveHandler handler) {
|
||||
doHandleResourceMove(event, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
protected void doHandleResourceMove(IResourceChangeEvent event, IResourceMoveHandler handler){
|
||||
switch (event.getType()) {
|
||||
case IResourceChangeEvent.PRE_CLOSE:
|
||||
|
|
|
@ -0,0 +1,449 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2007, 2008 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) - Bug 253911
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.settings.model.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.w3c.dom.Text;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @noextend This class is not intended to be subclassed by clients.
|
||||
* @noinstantiate This class is not intended to be instantiated by clients.
|
||||
*/
|
||||
@Deprecated
|
||||
public class XmlStorageElement implements ICStorageElement {
|
||||
|
||||
Element fElement;
|
||||
private ICStorageElement fParent;
|
||||
private List fChildList = new ArrayList();
|
||||
private boolean fChildrenCreated;
|
||||
private String[] fAttributeFilters;
|
||||
private String[] fChildFilters;
|
||||
private boolean fParentRefAlowed;
|
||||
|
||||
public XmlStorageElement(Element element){
|
||||
this(element, null, false);
|
||||
}
|
||||
|
||||
public XmlStorageElement(Element element, ICStorageElement parent, boolean alowReferencingParent){
|
||||
this(element, parent, alowReferencingParent, null, null);
|
||||
}
|
||||
|
||||
public XmlStorageElement(Element element,
|
||||
ICStorageElement parent,
|
||||
boolean alowReferencingParent,
|
||||
String[] attributeFilters,
|
||||
String[] childFilters){
|
||||
fElement = element;
|
||||
fParent = parent;
|
||||
fParentRefAlowed = alowReferencingParent;
|
||||
|
||||
if(attributeFilters != null && attributeFilters.length != 0)
|
||||
fAttributeFilters = attributeFilters.clone();
|
||||
|
||||
if(childFilters != null && childFilters.length != 0)
|
||||
fChildFilters = childFilters.clone();
|
||||
}
|
||||
|
||||
// public String[] getAttributeFilters(){
|
||||
// if(fAttributeFilters != null)
|
||||
// return (String[])fAttributeFilters.clone();
|
||||
// return null;
|
||||
// }
|
||||
|
||||
// public String[] getChildFilters(){
|
||||
// if(fChildFilters != null)
|
||||
// return (String[])fChildFilters.clone();
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// public boolean isParentRefAlowed(){
|
||||
// return fParentRefAlowed;
|
||||
// }
|
||||
|
||||
private void createChildren(){
|
||||
if(fChildrenCreated)
|
||||
return;
|
||||
|
||||
fChildrenCreated = true;
|
||||
NodeList list = fElement.getChildNodes();
|
||||
int size = list.getLength();
|
||||
for(int i = 0; i < size; i++){
|
||||
Node node = list.item(i);
|
||||
if(node.getNodeType() == Node.ELEMENT_NODE
|
||||
&& isChildAlowed(node.getNodeName())){
|
||||
createAddChild((Element)node, true, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private XmlStorageElement createAddChild(Element element,
|
||||
boolean alowReferencingParent,
|
||||
String[] attributeFilters,
|
||||
String[] childFilters){
|
||||
XmlStorageElement child = createChild(element, alowReferencingParent, attributeFilters, childFilters);
|
||||
fChildList.add(child);
|
||||
return child;
|
||||
}
|
||||
|
||||
protected XmlStorageElement createChild(Element element,
|
||||
boolean alowReferencingParent,
|
||||
String[] attributeFilters,
|
||||
String[] childFilters){
|
||||
return new XmlStorageElement(element, this, alowReferencingParent, attributeFilters, childFilters);
|
||||
}
|
||||
|
||||
public ICStorageElement[] getChildren() {
|
||||
return getChildren(XmlStorageElement.class);
|
||||
}
|
||||
|
||||
protected ICStorageElement[] getChildren(Class clazz){
|
||||
return getChildren(clazz, true);
|
||||
}
|
||||
|
||||
protected ICStorageElement[] getChildren(boolean load){
|
||||
return getChildren(XmlStorageElement.class, load);
|
||||
}
|
||||
|
||||
protected ICStorageElement[] getChildren(Class clazz, boolean load){
|
||||
if(load)
|
||||
createChildren();
|
||||
|
||||
ICStorageElement[] children = (ICStorageElement[])java.lang.reflect.Array.newInstance(
|
||||
clazz, fChildList.size());
|
||||
|
||||
return (ICStorageElement[])fChildList.toArray(children);
|
||||
}
|
||||
|
||||
public ICStorageElement getParent() {
|
||||
return fParentRefAlowed ? fParent : null;
|
||||
}
|
||||
|
||||
public String getAttribute(String name) {
|
||||
if(isPropertyAlowed(name) && fElement.hasAttribute(name))
|
||||
return fElement.getAttribute(name);
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isPropertyAlowed(String name){
|
||||
if(fAttributeFilters != null){
|
||||
return checkString(name, fAttributeFilters);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isChildAlowed(String name){
|
||||
if(fChildFilters != null){
|
||||
return checkString(name, fChildFilters);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkString(String name, String array[]){
|
||||
if(array.length > 0){
|
||||
for(int i = 0; i < array.length; i++){
|
||||
if(name.equals(array[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// protected void childRemoved(ICStorageElement child) {
|
||||
// fChildList.remove(child);
|
||||
// }
|
||||
|
||||
protected void removed(){
|
||||
// fElement.getParentNode().removeChild(fElement);
|
||||
fElement = null;
|
||||
// if(fParent != null)
|
||||
// ((XmlStorageElement)fParent).childRemoved(this);
|
||||
}
|
||||
|
||||
|
||||
public void removeChild(ICStorageElement el) {
|
||||
if(el instanceof XmlStorageElement){
|
||||
ICStorageElement[] children = getChildren();
|
||||
for(int i = 0; i < children.length; i++){
|
||||
if(children[i] == el){
|
||||
XmlStorageElement xmlEl = (XmlStorageElement)el;
|
||||
Node nextSibling = xmlEl.fElement.getNextSibling();
|
||||
fElement.removeChild(xmlEl.fElement);
|
||||
if (nextSibling != null && nextSibling.getNodeType() == Node.TEXT_NODE) {
|
||||
String value = nextSibling.getNodeValue();
|
||||
if (value != null && value.trim().length() == 0) {
|
||||
// remove whitespace
|
||||
fElement.removeChild(nextSibling);
|
||||
}
|
||||
}
|
||||
fChildList.remove(el);
|
||||
xmlEl.removed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeAttribute(String name) {
|
||||
if(isPropertyAlowed(name))
|
||||
fElement.removeAttribute(name);
|
||||
}
|
||||
|
||||
public void setAttribute(String name, String value) {
|
||||
if(isPropertyAlowed(name))
|
||||
fElement.setAttribute(name, value);
|
||||
}
|
||||
|
||||
public void clear(){
|
||||
createChildren();
|
||||
|
||||
ICStorageElement children[] = (ICStorageElement[])fChildList.toArray(new ICStorageElement[fChildList.size()]);
|
||||
for(int i = 0; i < children.length; i++){
|
||||
removeChild(children[i]);
|
||||
}
|
||||
|
||||
NamedNodeMap map = fElement.getAttributes();
|
||||
for(int i = 0; i < map.getLength(); i++){
|
||||
Node attr = map.item(i);
|
||||
if(isPropertyAlowed(attr.getNodeName()))
|
||||
map.removeNamedItem(attr.getNodeName());
|
||||
}
|
||||
|
||||
NodeList list = fElement.getChildNodes();
|
||||
for(int i = 0; i < list.getLength(); i++){
|
||||
Node node = list.item(i);
|
||||
if(node.getNodeType() == Node.TEXT_NODE)
|
||||
fElement.removeChild(node);
|
||||
}
|
||||
}
|
||||
|
||||
public ICStorageElement createChild(String name,
|
||||
boolean alowReferencingParent,
|
||||
String[] attributeFilters,
|
||||
String[] childFilters) {
|
||||
if(!isChildAlowed(name))
|
||||
return null;
|
||||
Element childElement = fElement.getOwnerDocument().createElement(name);
|
||||
fElement.appendChild(childElement);
|
||||
return createAddChild(childElement, alowReferencingParent, attributeFilters, childFilters);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return fElement.getNodeName();
|
||||
}
|
||||
|
||||
public ICStorageElement createChild(String name) {
|
||||
return createChild(name, true, null, null);
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
Text text = getTextChild();
|
||||
if(text != null)
|
||||
return text.getData();
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
Text text = getTextChild();
|
||||
if(value != null){
|
||||
if(text == null){
|
||||
text = fElement.getOwnerDocument().createTextNode(value);
|
||||
fElement.appendChild(text);
|
||||
} else {
|
||||
text.setData(value);
|
||||
}
|
||||
} else {
|
||||
if(text != null){
|
||||
fElement.removeChild(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Text getTextChild(){
|
||||
NodeList nodes = fElement.getChildNodes();
|
||||
Text text = null;
|
||||
for(int i = 0; i < nodes.getLength(); i++){
|
||||
Node node = nodes.item(i);
|
||||
if(node.getNodeType() == Node.TEXT_NODE){
|
||||
text = (Text)node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
public ICStorageElement importChild(ICStorageElement el) throws UnsupportedOperationException {
|
||||
return addChild(el, true, null, null);
|
||||
}
|
||||
|
||||
public ICStorageElement addChild(ICStorageElement el,
|
||||
boolean alowReferencingParent,
|
||||
String[] attributeFilters,
|
||||
String[] childFilters) throws UnsupportedOperationException {
|
||||
|
||||
if(!isChildAlowed(el.getName()))
|
||||
return null;
|
||||
|
||||
if(el instanceof XmlStorageElement){
|
||||
XmlStorageElement xmlStEl = (XmlStorageElement)el;
|
||||
Element xmlEl = xmlStEl.fElement;
|
||||
Document thisDoc = fElement.getOwnerDocument();
|
||||
Document otherDoc = xmlEl.getOwnerDocument();
|
||||
if(!thisDoc.equals(otherDoc)){
|
||||
xmlEl = (Element)thisDoc.importNode(xmlEl, true);
|
||||
} else {
|
||||
xmlEl = (Element)xmlEl.cloneNode(true);
|
||||
}
|
||||
|
||||
xmlEl = (Element)fElement.appendChild(xmlEl);
|
||||
return createAddChild(xmlEl, alowReferencingParent, attributeFilters, childFilters);
|
||||
} else {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getAttributeFilters(){
|
||||
if(fAttributeFilters != null)
|
||||
return fAttributeFilters.clone();
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public String[] getChildFilters(){
|
||||
if(fChildFilters != null)
|
||||
return fChildFilters.clone();
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
public boolean isParentRefAlowed(){
|
||||
return fParentRefAlowed;
|
||||
}
|
||||
|
||||
public boolean matches(ICStorageElement el){
|
||||
if(!getName().equals(el.getName()))
|
||||
return false;
|
||||
|
||||
if (!valuesMatch(getValue(), el.getValue()))
|
||||
return false;
|
||||
|
||||
|
||||
String[] attrs = getAttributeNames();
|
||||
String[] otherAttrs = el.getAttributeNames();
|
||||
if(attrs.length != otherAttrs.length)
|
||||
return false;
|
||||
|
||||
if(attrs.length != 0){
|
||||
Set set = new HashSet(Arrays.asList(attrs));
|
||||
set.removeAll(Arrays.asList(otherAttrs));
|
||||
if(set.size() != 0)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < attrs.length; i++){
|
||||
if(!getAttribute(attrs[i]).equals(el.getAttribute(attrs[i])))
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
XmlStorageElement[] children = (XmlStorageElement[])getChildren();
|
||||
ICStorageElement[] otherChildren = el.getChildren();
|
||||
|
||||
if(children.length != otherChildren.length)
|
||||
return false;
|
||||
|
||||
if(children.length != 0){
|
||||
for(int i = 0; i < children.length; i++){
|
||||
if(!children[i].matches(otherChildren[i]))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean valuesMatch(String value, String other) {
|
||||
if(value == null) {
|
||||
return other == null || other.trim().length() == 0;
|
||||
} else if (other == null) {
|
||||
return value.trim().length() == 0;
|
||||
} else {
|
||||
return value.trim().equals(other.trim());
|
||||
}
|
||||
}
|
||||
|
||||
public String[] getAttributeNames() {
|
||||
NamedNodeMap nodeMap = fElement.getAttributes();
|
||||
int length = nodeMap.getLength();
|
||||
List list = new ArrayList(length);
|
||||
for(int i = 0; i < length; i++){
|
||||
Node node = nodeMap.item(i);
|
||||
String name = node.getNodeName();
|
||||
if(isPropertyAlowed(name))
|
||||
list.add(name);
|
||||
}
|
||||
return (String[])list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public ICStorageElement createCopy() throws UnsupportedOperationException, CoreException {
|
||||
// todo Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public boolean equals(ICStorageElement other) {
|
||||
// todo Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public ICStorageElement[] getChildrenByName(String name) {
|
||||
// todo Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public boolean hasAttribute(String name) {
|
||||
// todo Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 5.1
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
// todo Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -65,6 +65,26 @@ public class SynchronizedStorageElement implements ICStorageElement {
|
|||
return new SynchronizedStorageElement(el);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a synchronized storage element from an existing storage element
|
||||
* All access to this ICStorageElement tree will be synchronized on the
|
||||
* returned ICStorageElement object.
|
||||
* @param el
|
||||
* @param lock
|
||||
* @return SynchronizedStorageElement wrapping the original ICStorageElement
|
||||
*/
|
||||
public static SynchronizedStorageElement synchronizedElement(ICStorageElement el, Object lock) {
|
||||
return new SynchronizedStorageElement(el, lock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the lock used to synchronize this SynchronizedStorage and its children
|
||||
*/
|
||||
public Object lock() {
|
||||
return fLock;
|
||||
}
|
||||
|
||||
|
||||
public void clear() {
|
||||
synchronized (fLock) {
|
||||
fEl.clear();
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<element name="extension">
|
||||
<annotation>
|
||||
<appinfo>
|
||||
<meta.element />
|
||||
<meta.element internal="true" />
|
||||
</appinfo>
|
||||
</annotation>
|
||||
<complexType>
|
||||
|
|
|
@ -17,7 +17,7 @@ import org.eclipse.cdt.core.settings.model.ICProjectDescription;
|
|||
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
/**
|
||||
* Models meta-data stored with a CDT project
|
||||
*
|
||||
|
@ -27,6 +27,9 @@ import org.eclipse.core.runtime.CoreException;
|
|||
*
|
||||
* @see ICDescriptorOperation
|
||||
* @see ICDescriptorManager
|
||||
*
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICDescriptor {
|
||||
public ICOwnerInfo getProjectOwner();
|
||||
|
@ -110,12 +113,26 @@ public interface ICDescriptor {
|
|||
*/
|
||||
public ICStorageElement getProjectStorageElement(String id) throws CoreException;
|
||||
|
||||
/**
|
||||
* This method has been superceded by {@link ICDescriptor#getProjectStorageElement(String)}
|
||||
* @param id an identifier that uniquely identifies the client
|
||||
* @return a non-null {@link Element} to which client specific meta-data may be attached
|
||||
* @throws CoreException
|
||||
* @deprecated
|
||||
* @noreference This method is not intended to be referenced by clients.
|
||||
* @use {@link ICDescriptor#getProjectStorageElement(String)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Element getProjectData(String id) throws CoreException;
|
||||
|
||||
/**
|
||||
* Remove the storage element with the given ID from the tree
|
||||
* @param id
|
||||
* @return the ICStorageElement removed or null if there was none for id
|
||||
* @throws CoreException
|
||||
* @since 5.1
|
||||
*/
|
||||
public void removeProjectStorageElement(String id) throws CoreException;
|
||||
public ICStorageElement removeProjectStorageElement(String id) throws CoreException;
|
||||
|
||||
/**
|
||||
* Saves any changes made to {@link ICStorageElement} objects obtained from {@link #getProjectStorageElement(String)}
|
||||
|
@ -130,4 +147,5 @@ public interface ICDescriptor {
|
|||
* @return the current setting {@link ICConfigurationDescription}
|
||||
*/
|
||||
ICConfigurationDescription getConfigurationDescription();
|
||||
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
|
@ -36,6 +39,8 @@ 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.SynchronizedStorageElement;
|
||||
import org.eclipse.cdt.internal.core.settings.model.xml.XmlStorage;
|
||||
import org.eclipse.cdt.internal.core.settings.model.xml.XmlStorageElement;
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
@ -46,6 +51,8 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
|||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.ILock;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
/**
|
||||
* Concrete ICDescriptor for a Project.
|
||||
|
@ -440,10 +447,88 @@ final public class CConfigBasedDescriptor implements ICDescriptor {
|
|||
}
|
||||
}
|
||||
|
||||
public void removeProjectStorageElement(String id) throws CoreException {
|
||||
/**
|
||||
* Backwards compatibility method which provides an XML Element.
|
||||
* Currently relies on the fact that the only implementation if ICStorageElement
|
||||
* in the core is XmlStorageElement.
|
||||
*/
|
||||
public Element getProjectData(String id) throws CoreException {
|
||||
try {
|
||||
fLock.acquire();
|
||||
fStorageDataElMap.put(id, null);
|
||||
// Check if the storage element already exists in our local map
|
||||
SynchronizedStorageElement storageEl = fStorageDataElMap.get(id);
|
||||
ICStorageElement el;
|
||||
if(storageEl == null) {
|
||||
el = fCfgDes.getStorage(id, true);
|
||||
try {
|
||||
el = el.createCopy();
|
||||
} catch (UnsupportedOperationException e) {
|
||||
throw ExceptionFactory.createCoreException(e);
|
||||
}
|
||||
|
||||
if (!(el instanceof XmlStorageElement))
|
||||
throw ExceptionFactory.createCoreException(
|
||||
"Internal Error: getProjectData(...) currently only supports XmlStorageElement types.", new Exception()); //$NON-NLS-1$
|
||||
|
||||
// Get the underlying Xml Element
|
||||
final Element xmlEl = ((XmlStorageElement)el).fElement;
|
||||
// This proxy synchronizes the storage element's root XML Element
|
||||
el = new XmlStorageElement((Element)Proxy.newProxyInstance(Element.class.getClassLoader(), new Class[]{Element.class}, new InvocationHandler(){
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
Method realMethod = xmlEl.getClass().getMethod(method.getName(), method.getParameterTypes());
|
||||
// Now just execute the method
|
||||
synchronized (xmlEl) {
|
||||
// If requesting the parent node, then we need another proxy
|
||||
// so that parent.removeChildNode(...) 'does the right thing'
|
||||
if (method.getName().equals("getParentNode")) { //$NON-NLS-1$
|
||||
final Node parent = (Node)realMethod.invoke(xmlEl, args);
|
||||
Node parentProxy = (Node)Proxy.newProxyInstance(Node.class.getClassLoader(), new Class[]{Node.class}, new InvocationHandler(){
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
Method realMethod = parent.getClass().getMethod(method.getName(), method.getParameterTypes());
|
||||
synchronized (xmlEl) {
|
||||
// Handle the remove child case
|
||||
if (method.getName().equals("removeChild")) { //$NON-NLS-1$
|
||||
if (args[0] instanceof Element && ((Element)args[0]).getAttribute(
|
||||
XmlStorage.MODULE_ID_ATTRIBUTE).length() > 0) {
|
||||
ICStorageElement removed = removeProjectStorageElement(((Element)args[0]).getAttribute(
|
||||
XmlStorage.MODULE_ID_ATTRIBUTE));
|
||||
if (removed != null)
|
||||
return ((XmlStorageElement)((SynchronizedStorageElement)removed).getOriginalElement()).fElement;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// else return the realMethod
|
||||
return realMethod.invoke(parent, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
return parentProxy;
|
||||
}
|
||||
// Otherwise just execute the method
|
||||
return realMethod.invoke(xmlEl, args);
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
storageEl = SynchronizedStorageElement.synchronizedElement(el, xmlEl);
|
||||
fStorageDataElMap.put(id, storageEl);
|
||||
} else {
|
||||
el = storageEl.getOriginalElement();
|
||||
if (!(el instanceof XmlStorageElement))
|
||||
throw ExceptionFactory.createCoreException(
|
||||
"Internal Error: getProjectData(...) currently only supports XmlStorageElement types.", new Exception()); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
return ((XmlStorageElement)el).fElement;
|
||||
} finally {
|
||||
fLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
public ICStorageElement removeProjectStorageElement(String id) throws CoreException {
|
||||
try {
|
||||
fLock.acquire();
|
||||
return fStorageDataElMap.put(id, null);
|
||||
} finally {
|
||||
fLock.release();
|
||||
}
|
||||
|
@ -623,7 +708,7 @@ final public class CConfigBasedDescriptor implements ICDescriptor {
|
|||
|
||||
if (synchStor != null ) {
|
||||
// Lock the synchronized storage element to prevent further changes
|
||||
synchronized (synchStor) {
|
||||
synchronized (synchStor.lock()) {
|
||||
if(reconcile(id, synchStor.getOriginalElement(), des))
|
||||
reconciled = true;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue