From 6a897468edca9b5b8eb24689b9adaa6d8f11a1cc Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Thu, 10 Jul 2003 17:50:34 +0000 Subject: [PATCH] - Added the ability to add arbitrary XML data to the cdtproject file. - Used to store the data that had been put in the cdtbuild file for Standard Make projects. - Cleaned up some of the exception handling in the StandardBuildManager. --- .../managed/tests/StandardBuildTests.java | 12 +- .../build/standard/StandardBuildManager.java | 103 ++++++------------ .../cdt/core/parser/IScannerInfoProvider.java | 3 +- .../org/eclipse/cdt/core/CProjectNature.java | 7 +- .../org/eclipse/cdt/core/ICDescriptor.java | 4 + .../cdt/internal/core/CDescriptor.java | 59 ++++++++++ .../cdt/ui/wizards/BuildPathInfoBlock.java | 34 ++++-- 7 files changed, 131 insertions(+), 91 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/StandardBuildTests.java b/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/StandardBuildTests.java index 3b929310bad..257da98bd78 100644 --- a/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/StandardBuildTests.java +++ b/core/org.eclipse.cdt.core.tests/build/org/eclipse/cdt/core/build/managed/tests/StandardBuildTests.java @@ -107,7 +107,7 @@ public class StandardBuildTests extends TestCase { return suite; } - private void checkDefaultProjectSettings(IProject project) { + private void checkDefaultProjectSettings(IProject project) throws Exception { assertNotNull(project); // There should not be any include path or defined symbols for the project @@ -128,7 +128,7 @@ public class StandardBuildTests extends TestCase { assertEquals(EMPTY_STRING, info.getIncrementalBuildArguments()); } - private void checkOverriddenProjectSettings(IProject project) { + private void checkOverriddenProjectSettings(IProject project) throws Exception { assertNotNull(project); // Check that the new stuff is there @@ -232,7 +232,7 @@ public class StandardBuildTests extends TestCase { removeProject(PROJECT_NAME); } - public void testProjectConversion() { + public void testProjectConversion() throws Exception { // Open the project IProject project = null; try { @@ -280,7 +280,7 @@ public class StandardBuildTests extends TestCase { /** * */ - public void testProjectCreation () { + public void testProjectCreation() throws Exception { // Create a new project IProject project = null; try { @@ -303,7 +303,7 @@ public class StandardBuildTests extends TestCase { checkDefaultProjectSettings(project); } - public void testProjectSettings() { + public void testProjectSettings() throws Exception { // Get the project IProject project = null; try { @@ -342,7 +342,7 @@ public class StandardBuildTests extends TestCase { checkOverriddenProjectSettings(project); } - public void testScannerListenerInterface() { + public void testScannerListenerInterface() throws Exception { // Get the project IProject project = null; try { diff --git a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/build/standard/StandardBuildManager.java b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/build/standard/StandardBuildManager.java index 263e307cbdc..6dc46993f61 100644 --- a/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/build/standard/StandardBuildManager.java +++ b/core/org.eclipse.cdt.core/build/org/eclipse/cdt/core/build/standard/StandardBuildManager.java @@ -1,9 +1,5 @@ package org.eclipse.cdt.core.build.standard; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -11,16 +7,9 @@ import java.util.List; import java.util.ListIterator; import java.util.Map; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; - -import org.apache.xerces.dom.DocumentImpl; -import org.apache.xml.serialize.Method; -import org.apache.xml.serialize.OutputFormat; -import org.apache.xml.serialize.Serializer; -import org.apache.xml.serialize.SerializerFactory; import org.eclipse.cdt.core.BuildInfoFactory; import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.ICDescriptor; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; @@ -30,9 +19,9 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.QualifiedName; -import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /********************************************************************** * Copyright (c) 2002,2003 Rational Software Corporation and others. @@ -49,18 +38,16 @@ public class StandardBuildManager implements IScannerInfoProvider { // Name we will use to store build property with the project private static final QualifiedName buildInfoProperty = new QualifiedName(CCorePlugin.PLUGIN_ID, "standardBuildInfo"); + private static final String ID = CCorePlugin.PLUGIN_ID + ".standardBuildInfo"; // Listeners interested in build model changes private static Map buildModelListeners; - private static final String FILE_NAME = ".cdtbuild"; - private static final String ROOT_ELEM_NAME = "StandardProjectBuildInfo"; - /** * @param project * @return */ - private static IStandardBuildInfo findBuildInfo(IResource resource, boolean create) { + private static IStandardBuildInfo findBuildInfo(IResource resource, boolean create) throws CoreException { IStandardBuildInfo buildInfo = null; // See if there's already one associated with the resource for this session try { @@ -87,11 +74,11 @@ public class StandardBuildManager implements IScannerInfoProvider { return buildInfo; } - public static IStandardBuildInfo getBuildInfo(IProject project) { + public static IStandardBuildInfo getBuildInfo(IProject project) throws CoreException { return findBuildInfo(project, false); } - public static IStandardBuildInfo getBuildInfo(IProject project, boolean create) { + public static IStandardBuildInfo getBuildInfo(IProject project, boolean create) throws CoreException { return findBuildInfo(project, create); } @@ -108,7 +95,7 @@ public class StandardBuildManager implements IScannerInfoProvider { /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.IScannerInfoProvider#managesResource(org.eclipse.core.resources.IResource) */ - public boolean managesResource(IResource resource) { + public boolean managesResource(IResource resource) throws CoreException { /* * Answers true if this project has a build info associated with it */ @@ -129,7 +116,9 @@ public class StandardBuildManager implements IScannerInfoProvider { return info == null ? false : true; } - public static void setPreprocessorSymbols(IProject project, String[] symbols) { + public static void setPreprocessorSymbols(IProject project, String[] symbols) + throws CoreException + { // Get the information for the project IStandardBuildInfo info = getBuildInfo(project); // Set the new information @@ -143,7 +132,9 @@ public class StandardBuildManager implements IScannerInfoProvider { } } - public static void setIncludePaths(IProject project, String[] paths) { + public static void setIncludePaths(IProject project, String[] paths) + throws CoreException + { // Get the build info for the project IStandardBuildInfo info = getBuildInfo(project); if (info != null) { @@ -177,25 +168,10 @@ public class StandardBuildManager implements IScannerInfoProvider { * information is then associated with the resource for the duration of * the session. */ - private static IStandardBuildInfo loadBuildInfo(IProject project) { - IStandardBuildInfo buildInfo = null; - IFile file = project.getFile(FILE_NAME); - if (!file.exists()) - return null; - - try { - InputStream stream = file.getContents(); - DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document document = parser.parse(stream); - Node rootElement = document.getFirstChild(); - if (rootElement.getNodeName().equals(ROOT_ELEM_NAME)) { - buildInfo = BuildInfoFactory.create(project, (Element)rootElement); - project.setSessionProperty(buildInfoProperty, buildInfo); - } - } catch (Exception e) { - buildInfo = null; - } - + private static IStandardBuildInfo loadBuildInfo(IProject project) throws CoreException { + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + IStandardBuildInfo buildInfo = BuildInfoFactory.create(project, descriptor.getProjectData(ID)); + project.setSessionProperty(buildInfoProperty, buildInfo); return buildInfo; } @@ -224,38 +200,25 @@ public class StandardBuildManager implements IScannerInfoProvider { * * @param project */ - public static void saveBuildInfo(IProject project) { - // Create document - Document doc = new DocumentImpl(); - Element rootElement = doc.createElement(ROOT_ELEM_NAME); - doc.appendChild(rootElement); - + public static void saveBuildInfo(IProject project) throws CoreException { + ICDescriptor descriptor = CCorePlugin.getDefault().getCProjectDescription(project); + + Element rootElement = descriptor.getProjectData(ID); + + // Clear out all current children + // Note: Probably would be a better idea to merge in the data + NodeList nodes = rootElement.getChildNodes(); + for (int i = 0; i < nodes.getLength(); ++i) { + Node node = nodes.item(i); + if (node instanceof Element) + rootElement.removeChild(nodes.item(i)); + } + // Save the build info IStandardBuildInfo buildInfo = getBuildInfo(project); if (buildInfo != null) - buildInfo.serialize(doc, rootElement); - - // Save the document - ByteArrayOutputStream s = new ByteArrayOutputStream(); - OutputFormat format = new OutputFormat(); - format.setIndenting(true); - format.setLineSeparator(System.getProperty("line.separator")); //$NON-NLS-1$ - String xml = null; - try { - Serializer serializer = SerializerFactory.getSerializerFactory(Method.XML).makeSerializer(new OutputStreamWriter(s, "UTF8"), format); - serializer.asDOMSerializer().serialize(doc); - xml = s.toString("UTF8"); //$NON-NLS-1$ - IFile rscFile = project.getFile(FILE_NAME); - InputStream inputStream = new ByteArrayInputStream(xml.getBytes()); - // update the resource content - if (rscFile.exists()) { - rscFile.setContents(inputStream, IResource.FORCE, null); - } else { - rscFile.create(inputStream, IResource.FORCE, null); - } - } catch (Exception e) { - return; - } + buildInfo.serialize(rootElement.getOwnerDocument(), rootElement); + descriptor.saveProjectData(); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScannerInfoProvider.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScannerInfoProvider.java index db15f417dd2..ad34dc829d4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScannerInfoProvider.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/IScannerInfoProvider.java @@ -1,6 +1,7 @@ package org.eclipse.cdt.core.parser; import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.CoreException; /********************************************************************** * Copyright (c) 2002,2003 Rational Software Corporation and others. @@ -31,7 +32,7 @@ public interface IScannerInfoProvider { * @param resource * @return */ - public boolean managesResource(IResource resource); + public boolean managesResource(IResource resource) throws CoreException; /** * The receiver will no longer notify the listener specified in diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CProjectNature.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CProjectNature.java index 99b3c8014df..0de56493305 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CProjectNature.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/CProjectNature.java @@ -296,8 +296,11 @@ public class CProjectNature implements IProjectNature { * @see IProjectNature#setProject */ public void setProject(IProject project) { - fProject= project; - fBuildInfo = StandardBuildManager.getBuildInfo(fProject, true); + try { + fProject= project; + fBuildInfo = StandardBuildManager.getBuildInfo(fProject, true); + } catch (CoreException e) { + } } } 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 8a6544204ae..b1e0b21aea0 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 @@ -12,6 +12,7 @@ package org.eclipse.cdt.core; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; +import org.w3c.dom.Element; public interface ICDescriptor { public ICOwnerInfo getProjectOwner(); @@ -27,4 +28,7 @@ public interface ICDescriptor { public void setPathEntries(ICPathEntry[] entries) throws CoreException; public ICPathEntry[] getPathEntries(); + + public Element getProjectData(String id) throws CoreException; + public void saveProjectData() throws CoreException; } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CDescriptor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CDescriptor.java index 3bffb908547..7cd41537942 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CDescriptor.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/core/CDescriptor.java @@ -23,6 +23,7 @@ import java.util.Map.Entry; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import org.apache.xerces.dom.DocumentImpl; import org.apache.xml.serialize.Method; @@ -60,6 +61,7 @@ public class CDescriptor implements ICDescriptor { private IProject fProject; private HashMap extMap = new HashMap(4); private HashMap extInfoMap = new HashMap(4); + private Document dataDoc; static final String DESCRIPTION_FILE_NAME = ".cdtproject"; private static final char[][] NO_CHAR_CHAR = new char[0][]; @@ -67,6 +69,9 @@ public class CDescriptor implements ICDescriptor { private static final String PROJECT_EXTENSION = "extension"; private static final String PROJECT_EXTENSION_ATTRIBUTE = "attribute"; private static final String PATH_ENTRY = "cpathentry"; + private static final String PROJECT_DATA = "data"; + private static final String PROJECT_DATA_ITEM = "item"; + private static final String PROJECT_DATA_ID = "id"; private boolean fDirty; private boolean autoSave; @@ -328,6 +333,8 @@ public class CDescriptor implements ICDescriptor { if (entry != null) { pathEntries.add(entry); } + } else if (childNode.getNodeName().equals(PROJECT_DATA)) { + decodeProjectData((Element)childNode); } } } @@ -450,6 +457,7 @@ public class CDescriptor implements ICDescriptor { configRootElement.setAttribute("id", fOwner.getID()); //$NON-NLS-1$ encodeProjectExtensions(doc, configRootElement); encodePathEntries(doc, configRootElement); + encodeProjectData(doc, configRootElement); return serializeDocument(doc); } @@ -545,4 +553,55 @@ public class CDescriptor implements ICDescriptor { } return (ICExtension) cExtension; } + + // The project data allows for the storage of any structured information + // into the cdtproject file. + private Document getProjectDataDoc() throws CoreException { + if (dataDoc == null) { + try { + dataDoc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + throw new CoreException( + new Status( + IStatus.ERROR, + CCorePlugin.PLUGIN_ID, + IStatus.ERROR, + "getProjectDataDoc", + e)); + } + Element rootElem = dataDoc.createElement(PROJECT_DATA); + dataDoc.appendChild(rootElem); + } + return dataDoc; + } + + private void decodeProjectData(Element data) throws CoreException { + Document doc = getProjectDataDoc(); + doc.getDocumentElement().appendChild(doc.importNode(data, true)); + } + + public Element getProjectData(String id) throws CoreException { + NodeList nodes = getProjectDataDoc().getDocumentElement().getElementsByTagName(PROJECT_DATA_ITEM); + for (int i = 0; i < nodes.getLength(); ++i) { + Element element = (Element)nodes.item(i); + if (element.getAttribute(PROJECT_DATA_ID).equals(id)) + return element; + } + + // Not found, make a new one + Element element = dataDoc.createElement(PROJECT_DATA_ITEM); + element.setAttribute(PROJECT_DATA_ID, id); + dataDoc.getDocumentElement().appendChild(element); + return element; + } + + public void saveProjectData() throws CoreException { + setDirty(); + } + + private void encodeProjectData(Document doc, Element root) { + // Don't create or encode the doc if it isn't there already + if (dataDoc != null) + root.appendChild(doc.importNode(dataDoc.getDocumentElement(), true)); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/BuildPathInfoBlock.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/BuildPathInfoBlock.java index d5d74c7bb84..4f30a79a671 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/BuildPathInfoBlock.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/wizards/BuildPathInfoBlock.java @@ -265,14 +265,18 @@ public class BuildPathInfoBlock implements IWizardTab { monitor = new NullProgressMonitor(); } if (project != null) { - // Store the paths and symbols - monitor.beginTask("Setting Include Paths", 1); - StandardBuildManager.setIncludePaths(project, getPathListContents()); - - monitor.beginTask("Setting Defined Symbols", 1); - StandardBuildManager.setPreprocessorSymbols(project, getSymbolListContents()); - - StandardBuildManager.saveBuildInfo(project); + try { + // Store the paths and symbols + monitor.beginTask("Setting Include Paths", 1); + StandardBuildManager.setIncludePaths(project, getPathListContents()); + + monitor.beginTask("Setting Defined Symbols", 1); + StandardBuildManager.setPreprocessorSymbols(project, getSymbolListContents()); + + StandardBuildManager.saveBuildInfo(project); + } catch (CoreException e) { + // Should probably tell someone + } } } @@ -589,15 +593,21 @@ public class BuildPathInfoBlock implements IWizardTab { private void setPathListContents() { if (project != null) { - IStandardBuildInfo info = StandardBuildManager.getBuildInfo(project); - pathList.setItems(info.getIncludePaths()); + try { + IStandardBuildInfo info = StandardBuildManager.getBuildInfo(project); + pathList.setItems(info.getIncludePaths()); + } catch (CoreException e) { + } } } private void setSymbolListContents() { if (project != null) { - IStandardBuildInfo info = StandardBuildManager.getBuildInfo(project); - symbolList.setItems(info.getPreprocessorSymbols()); + try { + IStandardBuildInfo info = StandardBuildManager.getBuildInfo(project); + symbolList.setItems(info.getPreprocessorSymbols()); + } catch (CoreException e) { + } } }