diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java
index 4a07bbb340c..8636b6030f2 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/CProjectDescriptionStorageManager.java
@@ -178,7 +178,8 @@ public class CProjectDescriptionStorageManager {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
- transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ // Indentation is done with XmlUtil.prettyFormat(doc)
+ transformer.setOutputProperty(OutputKeys.INDENT, "no"); //$NON-NLS-1$
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(stream);
transformer.transform(source, result);
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java
index 01c99e4e24c..d8985101296 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java
@@ -546,7 +546,8 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
- transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ // Indentation is done with XmlUtil.prettyFormat(doc)
+ transformer.setOutputProperty(OutputKeys.INDENT, "no"); //$NON-NLS-1$
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(stream);
transformer.transform(source, result);
@@ -584,6 +585,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
utfString = stream.toString("UTF-8"); //$NON-NLS-1$
String eol = Util.getLineSeparator(projectFile);
utfString = XmlUtil.replaceLineSeparatorInternal(utfString, eol);
+ utfString = XmlUtil.insertNewlineAfterXMLVersionTag(utfString, eol);
} finally {
if (stream != null)
stream.close(); // Cleanup the stream
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlStorageElement.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlStorageElement.java
index 45e6cec2b5b..47941d136b6 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlStorageElement.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlStorageElement.java
@@ -514,7 +514,10 @@ public class XmlStorageElement implements ICStorageElement {
try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
Transformer transformer = TransformerFactory.newInstance().newTransformer();
- transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ // Indentation is done with XmlUtil.prettyFormat(doc).
+ // For debugging, the prettyFormat may not have been run yet,
+ // so turning this to "yes" may be helpful on occasion.
+ transformer.setOutputProperty(OutputKeys.INDENT, "no"); //$NON-NLS-1$
DOMSource source = new DOMSource(fElement);
StreamResult result = new StreamResult(stream);
diff --git a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java
index f012414b3b3..af9095b8bd4 100644
--- a/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java
+++ b/core/org.eclipse.cdt.core/utils/org/eclipse/cdt/internal/core/XmlUtil.java
@@ -133,6 +133,11 @@ public class XmlUtil {
* to pretty print XML. This method prepares DOM {@code Document} for the transformer
* to be pretty printed, i.e. providing proper indentations for enclosed tags.
*
+ * Note, while this was originally a workaround, the user community of CDT
+ * has come to expect the format of the .cproject file and others to be
+ * unchanging, therefore CDT always uses this and does not attempt
+ * to format with the Transformer.
+ *
* @param doc - DOM document to be pretty printed
*/
public static void prettyFormat(Document doc) {
@@ -144,6 +149,11 @@ public class XmlUtil {
* to pretty print XML. This method prepares DOM {@code Document} for the transformer
* to be pretty printed, i.e. providing proper indentations for enclosed tags.
*
+ * Note, while this was originally a workaround, the user community of CDT
+ * has come to expect the format of the .cproject file and others to be
+ * unchanging, therefore CDT always uses this and does not attempt
+ * to format with the Transformer.
+ *
* @param doc - DOM document to be pretty printed
* @param indent - custom indentation as a string of white spaces
*/
@@ -291,6 +301,7 @@ public class XmlUtil {
String utfString = new String(toByteArray(doc), ENCODING_UTF_8);
utfString = XmlUtil.replaceLineSeparatorInternal(utfString, lineSeparator);
+ utfString = XmlUtil.insertNewlineAfterXMLVersionTag(utfString, lineSeparator);
FileOutputStream output = getFileOutputStreamWorkaround(storeFile);
output.write(utfString.getBytes(ENCODING_UTF_8));
@@ -347,7 +358,8 @@ public class XmlUtil {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
transformer.setOutputProperty(OutputKeys.ENCODING, ENCODING_UTF_8);
- transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
+ // Indentation is done with XmlUtil.prettyFormat(doc).
+ transformer.setOutputProperty(OutputKeys.INDENT, "no"); //$NON-NLS-1$
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(stream);
transformer.transform(source, result);
@@ -375,6 +387,30 @@ public class XmlUtil {
return string;
}
+ /**
+ * Do not use outside of CDT.
+ *
+ * This method is used to workaround changing implementations of {@link javax.xml.transform.Transformer}
+ * to maintain the same file content for CDT users. See {@link #prettyFormat(Document)} and Bug 565628
+ *
+ * This method inserts a newline between the ... xml ... ?> and first tag in the document
+ *
+ * @noreference This method is not intended to be referenced by clients.
+ * This is an internal method which ideally should be made private.
+ */
+ public static String insertNewlineAfterXMLVersionTag(String string, String lineSeparator) {
+ if (string == null) {
+ return null;
+ }
+
+ int indexOf = string.indexOf("?><"); //$NON-NLS-1$
+ if (indexOf < 0 || string.length() < indexOf + 2) {
+ return string;
+ }
+
+ return string.substring(0, indexOf + 2) + lineSeparator + string.substring(indexOf + 2);
+ }
+
/**
* Serialize XML Document into a workspace file.
* Note: clients should synchronize access to this method.
@@ -390,6 +426,7 @@ public class XmlUtil {
String utfString = new String(toByteArray(doc), ENCODING_UTF_8);
String lineSeparator = Util.getLineSeparator(file);
utfString = XmlUtil.replaceLineSeparatorInternal(utfString, lineSeparator);
+ utfString = XmlUtil.insertNewlineAfterXMLVersionTag(utfString, lineSeparator);
byte[] newContents = utfString.getBytes(ENCODING_UTF_8);
InputStream input = new ByteArrayInputStream(newContents);