Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Recoskie2009-02-03 19:17:38 +0000
committerChris Recoskie2009-02-03 19:17:38 +0000
commit6b87d8c5bc2287270c44a50f67c2edc7c025e404 (patch)
tree8f9fe29cda73b6a3825d263517c545ce190fb00d
parent8d8060f5af82473a1cdad9d052cc61e9f1a75b57 (diff)
downloadorg.eclipse.cdt-6b87d8c5bc2287270c44a50f67c2edc7c025e404.tar.gz
org.eclipse.cdt-6b87d8c5bc2287270c44a50f67c2edc7c025e404.tar.xz
org.eclipse.cdt-6b87d8c5bc2287270c44a50f67c2edc7c025e404.zip
RESOLVED - bug 252966: ProjectDescription Storage: It should be possible to extend / override persistence mechanism
https://bugs.eclipse.org/bugs/show_bug.cgi?id=252966
-rw-r--r--core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorOldTests.java404
-rw-r--r--core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java2
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICProjectDescriptionManager.java5
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingsStorage.java9
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICStorageElement.java6
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/XmlStorageUtil.java3
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/ResourceChangeHandlerBase.java11
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/XmlStorageElement.java449
-rw-r--r--core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SynchronizedStorageElement.java20
-rw-r--r--core/org.eclipse.cdt.core/schema/CProjectDescriptionStorage.exsd2
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICDescriptor.java22
-rw-r--r--core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CConfigBasedDescriptor.java91
12 files changed, 1015 insertions, 9 deletions
diff --git a/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorOldTests.java b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorOldTests.java
new file mode 100644
index 00000000000..90a7afefa20
--- /dev/null
+++ b/core/org.eclipse.cdt.core.tests/misc/org/eclipse/cdt/core/cdescriptor/tests/CDescriptorOldTests.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java
index 0cd996bc3b0..367770d9ea4 100644
--- a/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java
+++ b/core/org.eclipse.cdt.core.tests/suite/org/eclipse/cdt/core/suite/AutomatedIntegrationSuite.java
@@ -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());
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICProjectDescriptionManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICProjectDescriptionManager.java
index c743ee791a0..26e48178015 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICProjectDescriptionManager.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICProjectDescriptionManager.java
@@ -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;
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingsStorage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingsStorage.java
index 1f69fd38f6a..c958c61f6c5 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingsStorage.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICSettingsStorage.java
@@ -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);
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICStorageElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICStorageElement.java
index e1a4f6e8946..f208ff1cbbc 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICStorageElement.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/ICStorageElement.java
@@ -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);
}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/XmlStorageUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/XmlStorageUtil.java
index a8b04388450..54ece8c61bd 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/XmlStorageUtil.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/XmlStorageUtil.java
@@ -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 {
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/ResourceChangeHandlerBase.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/ResourceChangeHandlerBase.java
index 7988ef6c4b2..cf8b79aec48 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/ResourceChangeHandlerBase.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/ResourceChangeHandlerBase.java
@@ -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:
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/XmlStorageElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/XmlStorageElement.java
new file mode 100644
index 00000000000..845208296a7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/settings/model/util/XmlStorageElement.java
@@ -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;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SynchronizedStorageElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SynchronizedStorageElement.java
index 045a1e86335..b302db87460 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SynchronizedStorageElement.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/SynchronizedStorageElement.java
@@ -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();
diff --git a/core/org.eclipse.cdt.core/schema/CProjectDescriptionStorage.exsd b/core/org.eclipse.cdt.core/schema/CProjectDescriptionStorage.exsd
index 5ea7a2549e0..fbf9952a7c8 100644
--- a/core/org.eclipse.cdt.core/schema/CProjectDescriptionStorage.exsd
+++ b/core/org.eclipse.cdt.core/schema/CProjectDescriptionStorage.exsd
@@ -13,7 +13,7 @@
<element name="extension">
<annotation>
<appinfo>
- <meta.element />
+ <meta.element internal="true" />
</appinfo>
</annotation>
<complexType>
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICDescriptor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICDescriptor.java
index 9576a4f0f9b..a7401e723a2 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICDescriptor.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/ICDescriptor.java
@@ -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();
@@ -111,11 +114,25 @@ 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();
+
}
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CConfigBasedDescriptor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CConfigBasedDescriptor.java
index c19e5f8d5a4..3baa875ec32 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CConfigBasedDescriptor.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CConfigBasedDescriptor.java
@@ -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();
+ // 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();
- fStorageDataElMap.put(id, null);
+ 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;
}

Back to the top