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 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);