1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 17:56:01 +02:00

Bug 565628: Handle formatting/indentation of XML files with CDT code only

The javax.xml.transform.Transformer as used in CDT did not fully
indent, despite INDENT=yes being set (See Bug 286751).

However in Java 11, INDENT=yes started doing "more", so to maintain
compatibility with how .cproject and others are formatted, turn
off INDENT=yes and rely solely on XmlUtil.prettyFormat and the
related workarounds in xmlutil.

Change-Id: Icec04cfd3f9f1290593cff8b15b398b41c9d932a
This commit is contained in:
Jonah Graham 2020-08-11 14:07:03 -04:00
parent 6f3cb8014b
commit ee0e931b42
4 changed files with 47 additions and 4 deletions

View file

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

View file

@ -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

View file

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

View file

@ -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;
}
/**
* <b>Do not use outside of CDT.</b>
*
* 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.<br/>
* 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);